Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

State of the Art navigation & routing with Xamarin Forms and ReactiveUI

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.

like image 870
Morgan Touverey Quilling Avatar asked Nov 07 '22 14:11

Morgan Touverey Quilling


1 Answers

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

like image 78
Steve Chadbourne Avatar answered Dec 21 '22 22:12

Steve Chadbourne