I have an MvvmCross application, and I am using the MvvmCross ViewModel Lifecycle functions to realize certain actions when the view appears, moves to background, and moves to foreground:
Those functions work great in my Android device. But for iOS they do not get fired when the application moves to background or to foreground (although, except for ViewDestroy, they fire when navigating between the screens in the app in iOS)
1)Is that the intended behavior, or I am missing something?
2)If so, what is the approach we have to follow, when there are actions that we need to do when the app moves to foreground/background (like stopping timers)? Should we maybe have two implementations one for android, and one for ios? I also tried the ViewDidDisappear method in the MvxBaseViewController, still it is not activated when the app moves to background. There is a way in Xamarin/MvvmCross to hook into the native ios applicationDidEnterBackground?
Edit: I have tried Ranjit´s answer, but it seems to be a problem subscribing to the message. Here is my test code:
AppDelegate.cs:
public override void DidEnterBackground(UIApplication application)
{
base.DidEnterBackground(application);
var message = new LocationMessage(
this,
34
);
_messenger = Mvx.IoCProvider.Resolve<IMvxMessenger>();
_messenger.Publish(message);
}
Base class:
public abstract class GenericMvxViewModel : MvxViewModel
{
private IMvxMessenger _messenger;
protected GenericMvxViewModel()
{
// other stuff
_messenger = Mvx.IoCProvider.Resolve<IMvxMessenger>();
_messenger.Subscribe<LocationMessage>(OnLocationMessage);
}
protected virtual void OnLocationMessage(LocationMessage locationMessage){}
}
ViewModel:
public class MyClassViewModel : GenericMvxViewModel
{
protected override void OnLocationMessage(LocationMessage locationMessage)
{
Debug.WriteLine(locationMessage.Lat);
}
}
The message is published in the AppDelegate.cs, but the OnLocationMessage method in the viewmodel is never executed.
Also I was wondering how to unsubscribe properly the message. ViewDestroy seems the most natural place, but as mentioned before it is never called on iOS
Your code should work. I am using same kind of function in my app it was working fine
GenericMvxViewModel Code
private MvxSubscriptionToken _locationEventToken;
public override void ViewAppeared()
{
SubscribeBaseLocationEvent();
base.ViewAppeared();
}
public override void ViewDisappeared()
{
if (StaticStorage.IsApplicationInForeground)
{
UnSubscribeBaseLocationEvent();
}
base.ViewDisappeared();
}
public void SubscribeBaseLocationEvent()
{
if (_locationEventToken == null)
{
_locationEventToken = Messenger.Subscribe<LocationMessage>(OnLocationMessage);
}
}
public void UnSubscribeBaseLocationEvent()
{
if (_locationEventToken != null)
{
Messenger.Unsubscribe<LocationMessage>(_locationEventToken);
_locationEventToken = null;
}
}
AppDelegate Code
public override void DidEnterBackground(UIApplication application)
{
base.DidEnterBackground(application);
StaticStorage.IsApplicationInForeground = false;
_messenger.Publish(new LocationMessage( this, 34 ));
}
public override void WillEnterForeground(UIApplication application)
{
StaticStorage.IsApplicationInForeground = true;
}
Android
protected override void OnResume()
{
StaticStorage.IsApplicationInForeground = true;
base.OnResume();
}
protected override void OnStop()
{
StaticStorage.IsApplicationInForeground = false;
base.OnStart();
}
When application is moving from one view to other view, we need to unsubscribe the event. But not when application moves to background. So, IsApplicationInForeground flag will help to solve this issue for android. Because for android when application goes to background ViewDisappeared will be called.
In my case. I have one common activity which holds remaining all views of fragment. So, I have added this code in common activity. Not sure in your case how you are using. But implementation will be similar.