5

Every year or so, I've got an mobile app to do, and I choose Xamarin Forms to do it. Before starting with a blank project, I'm trying to see what frameworks and patterns are "trending" and I'm trying to build something solid.

On my last app, my research led me to a custom setup with Autofac for IoC and MvvmLight, plus a bunch of other custom services that played nice with them.

As I'm coming from the web, I did not escape to the Reactive Extensions wave, especially as an Angular dev. So, this time, my setup is based on Splat (I prefer Autofac, but.. tradeoffs, you know) and ReactiveUI.

I'm pretty happy with it. However, in my last applications, there's still one thing I'm really unhappy with: navigation. Most examples on the web are basic (push/pop on basic NavigationPages), there are no libraries out there that do it well, and ReactiveUI's navigation is... well, limited.

So I had to make my own root view and navigation service, I mean, I did not wrote it, but Kent Boogaart did in a blog post (if you're interested in answering my question, I suggest you to look at the impl to get a better idea of the limitations given my use cases). And it looks good. And I enjoyed it at first, before I had to handle more complex scenarios, like a login page that leads to MasterDetailPage, and TabbedPages.

And boom, again, I spend hours fighting with obscure X.F or Android exceptions and complex navigation logic in order to make a service that handles very common use cases. I'm unable to find valid examples on the net, it looks like that everyone only builds example apps with three screens without anything else than a NavigationPage.

I'm lost.

Here's the APIs I currently have, from Kent Boogaart's blog.

The root view:

public interface IView
{
    IObservable<IViewModel> PagePopped { get; }

    IObservable<Unit> PushPage(IViewModel pageViewModel, string contract, bool resetStack, bool animate);

    IObservable<Unit> PopPage(bool animate);

    IObservable<Unit> PushModal(IViewModel modalViewModel, string contract);

    IObservable<Unit> PopModal();
}

The service:

public interface IViewStackService
{
    IView View { get; }

    IObservable<IImmutableList<IViewModel>> PageStack { get; }

    IObservable<IImmutableList<IViewModel>> ModalStack { get; }

    IObservable<Unit> PushPage(
        IViewModel page,
        string contract = null,
        bool resetStack = false,
        bool animate = true);

    IObservable<Unit> PopPage(bool animate = true);

    IObservable<Unit> PushModal(IViewModel modal, string contract = null);

    IObservable<Unit> PopModal();
}

What I'm trying to do:

--------------------------
| navigation page        | <- user not logged in, it's the root page
| --------- ------------ |
| | login | | register | |
| --------- ------------ |
|------------------------|
      |
      | -> user logs in
      |    via a hack, i can replace the root page with the masterdetails created by hand
      |    and reuse my previous root navigation page from the login screen as the new root,
      |    setting it as the Detail page (so the MasterDetail is not handled by my service)
      V
----------------------------------
| masterdetail page              |
| --------------------------     | -> this begins to get really complicated
| | detail 1 / tabbed page |     |
| | ---------- ----------  |     |
| | | page 1 | | page 2 |  |     |
| | ---------- ----------  |     |
| --------------------------     |
| ------------------------------ |
| | detail 2 / navigation page | | -> this could be doable with the current implementation
| | ----------  -------        | |    but erh..
| | | page 1 |->| etc |        | |
| | ----------  -------        | |
| ------------------------------ |
----------------------------------

As you can see, the first problem is that the current service only handles one root navigation page, and I can't handle MasterDetailPages or TabbedPages correctly and reliably.

So my overall question is: have you good examples showing a real app with real navigation? Have you encountered the same questioning? What would be your approach? I'm open to comments, code snippets or NuGet packages. Everything that could help me focus on the actual app, rather than building my own framework over and over again, without ever being really satisfied.

Morgan Touverey Quilling
  • 4,181
  • 4
  • 29
  • 41
  • A unexplained downvote? sorry for not asking a question that allows easy rep farming. – Morgan Touverey Quilling Nov 07 '17 at 20:26
  • I don't agree with the downvote, i upvoted :) – Maximus Nov 07 '17 at 20:29
  • From https://stackoverflow.com/help/on-topic: "Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam" – Shlomo Nov 07 '17 at 20:33
  • I'm genuinely surprised that this is off-topic. I regularly find (and search for!) topics like that and I find them to be very instructive and useful. [Like the one I linked in my question](https://stackoverflow.com/questions/26898381/reactiveui-view-viewmodel-injection-and-di-in-general). Should I post a new question "help, this service doesn't work, could you please fix it"? If it's a wording problem... – Morgan Touverey Quilling Nov 07 '17 at 22:20
  • An interesting question. Bit of a knee jerk reaction to label it as off topic just because its not a question about broken code. – Steve Chadbourne Nov 07 '17 at 23:01

2 Answers2

1

I use the MVVMV Framework Freshmvvm. It has nice navigation functionality and allows me to swap between navigation "stacks" when moving from the login stack to the main stack. It has a similar interface to the one you showed. It allows me to extend or replace the navigation functionality. It provides a basic IOC container that can be swapped out. It can be extended to support master detail with tabbed pages. I have not found a situation I can't use it or extend it.

Here are the main details

And here is some more information about implementing custom navigation

Steve Chadbourne
  • 6,873
  • 3
  • 54
  • 82
  • Very promising indeed, it looks quite flexible at a first glance. I'm just wondering if that would not add to much overhead/complexity as I already have ReactiveUI and Splat - I'd need two compatibility layers (ReactiveUI needs Splat). I'll look into it to see if that could be done nicely, or just get some inspiration from it. Thanks! – Morgan Touverey Quilling Nov 07 '17 at 23:16
0

I have an example app on github using ReactiveUI that switches between login page and MasterDetailPage. I have no idea if I've implemented this correctly or not but it appears to work great. Here is the link

Post Impatica
  • 14,999
  • 9
  • 67
  • 78