Search code examples
androidiosobjective-cswiftj2objc

How to handle UI based Navigation in Cross Platform Apps?


Assume that you have a cross platform application. The application runs on Android and on iOS. Your shared language across both platforms is Java. Typically you would write your business logic in Java and all you UI specific part in Java (for Android) and Objective-C (for iOS).

Typically when you implement the MVP pattern in a cross platform, cross language application you would have the Model and the Presenter in Java and provide a Java interface for your Views which is known to your presenters. This way your shared Java presenters can communicate with whatever view implementation you use on the platform specific part.

Lets assume we want to write a iOS app with a Java part which could be shared later on with the same Android app. Here is a graphical representation of the design:

enter image description here

On the left side there is the Java part. In Java you write your models, controllers as well as your view interfaces. You make all the wiring using dependency injection. Then the Java code can be translated to Objective-C using J2objc.

On the right side you have the Objective-C part. Here your UIViewController's can implement the Java interfaces which where translated into ObjectiveC protocols.

Problem:

What I am struggling about is how navigation between views takes place. Assume you are on UIViewControllerA and you tap a button which should bring you to UIViewControllerB. What would you do?

Case 1:

enter image description here

You report the button tap to the Java ControllerA (1) of UIViewControllerA and the Java ControllerA calls Java ControllerB (2) which is linked to UIViewControllerB (3). Then you have the problem that you do not know from the Java Controller side how to insert the UIViewControllerB in the Objective-C View hierarchy. You cannot handle that from the Java side because you have only access to the View interfaces.

Case 2:

enter image description here

You can make the transition to UIViewControllerB whether it is modal or with a UINavigationController or whatever (1). Then, first you need the correct instance of UIViewControllerB which is bind to the Java ControllerB (2). Otherwise the UIViewControllerB could not interact which the Java ControllerB (2,3). When you have the correct instance you need to tell Java ControllerB that the View (UIViewControllerB) has been revealed.

I am still struggling with this problem of how to handle the navigation between different controllers.

How can I model the navigation between different Controllers and handle the cross platform View changes appropriately?


Solution

  • I would recommend that you use some kind of slot mechanism. Similar to what other MVP frameworks use.

    Definition: A slot is a part of a view where other views can be inserted.

    In your presenter you can define as many slots as you want:

    GenericSlot slot1 = new GenericSlot();
    GenericSlot slot2 = new GenericSlot();
    GenericSlot slot3 = new GenericSlot();
    

    These slots must have a reference in the Presenter's view. You can implement a

    setInSlot(Object slot, View v);
    

    method. If you implement setInSlot in a view then the view can decide how it should be included.

    Have a look at how slots are implemented here.