Search code examples
c#xamarin.androidxamarin.iosmvvmcross

MvvmCross - How to make navigation call to Mvx View from UIApplication Xamarin.iOS


My goal is to redirect user back to login screen after idle timed out. I have this code to countdown after each click/touch. It works well but my current problem is I have no idea to redirect user back to login screen. Since this is MvvmCross 4.4 project, there is not much documentation to look for. If I can also get the example code for Android, that would be very helpful. I will appreciate.

Below is the code I put in Main.cs

public class Application{  

    static void Main(string[] args){  
        //UIApplication.Main(args, null, "AppDelegate");  
        UIApplication.Main(args, "MyApplication", "AppDelegate");  
    }  

}  

//DELEGATE  
[Register("MyApplication")]  
public class MyApplication : UIApplication {  

    public override void SendEvent(UIEvent uievent) {  
        base.SendEvent(uievent);  
        var allTouches = uievent.AllTouches;  
        if (allTouches.Count > 0) {  
            var phase = ((UITouch)allTouches.AnyObject).Phase;  
            if (phase == UITouchPhase.Began || phase == UITouchPhase.Ended)  
                ResetIdleTimer();  
        }  
    }  

    NSTimer idleTimer;  
    void ResetIdleTimer() {  
        if (idleTimer != null) {  
            idleTimer.Invalidate();  
            idleTimer.Dispose();  
        }  

        idleTimer = NSTimer.CreateScheduledTimer(TimeSpan.FromMinutes(0.5), TimerExceeded);  
    }  

    void TimerExceeded(NSTimer obj) {  

        MvxiOSToastService toastService = new MvxiOSToastService();
        toastService.DisplayMessageAndDoSomething("You are going to be timed out.","Idle time exceeded.", RedirectToLogin);  

        Console.WriteLine("idle time exceeded");  
    }  

    void RedirectToLogin() {  

        var window = UIApplication.SharedApplication.KeyWindow;  
        var vc = window.RootViewController;  

        //ERROR HERE  
        var nextVC = new LoginView();   
        vc.ShowViewController(nextVC, this);  
        //----------
    }  
}  

Solution

  • You'll need to resolve the instance of your view presenter and get the currently presented view from there. Once you have that, you can access the ViewModel object and make the below calls to use MvvmCross navigation.

    If you have access to the RootViewController then

    void RedirectToLogin() {  
        var window = UIApplication.SharedApplication.KeyWindow;  
        var vc = window.RootViewController;  
    
        var mvxView = vc as IMvxIosView;  
        var vm = mvxView.ViewModel;
    
        vm.ShowViewModel<TViewModel>();
    }
    

    MvvmCross before 5

    https://www.mvvmcross.com/documentation/fundamentals/view-presenters

    ShowViewModel<TViewModel>()
    

    MvvmCross 5+

    Resolve an instance of your navigation service and use that to make the navigation call to your login screen.

    So something like:

    Mvx.Resolve<IMvxNavigationService>().Navigate<LoginViewModel>();