Я разрабатываю мобильное приложение для платформ iOS и Android, используя Xamarin и MvvmCross.Я могу получать push-уведомления, когда приложение находится на переднем плане и в фоновом режиме.
Когда приложение закрыто, я также получаю push-уведомления, и когда я нажимаю на них, приложение запускается, но я не знаю, как определить, запущено ли приложение из-за того, что пользователь нажал на значок приложения или потому, чтонажали на уведомление.Я хочу перейти к конкретной модели представления, когда приложение было закрыто и запущено с помощью push-уведомления.
Я нашел эту статью, в которой предлагается решение, которое я еще не реализовал, которое могло бы решитьпроблема в платформо-зависимом коде (iOS):
https://theconfuzedsourcecode.wordpress.com/2015/09/22/handling-push-notifications-in-xamarin-ios-when-app-is-closed/
Также в этом направлении есть ответ на форумах xamarin:
https://forums.xamarin.com/discussion/67698/ios-notifications-while-app-is-closed
Если пользователь нажимает на отображаемый баннер, вызывается метод> AppDelegate.FinishedLaunching.Переданные параметры NSDictionary of> будут содержать> UIApplication.LaunchOptionsRemoteNotificationKey, чтобы сообщить, что приложение> было запущено из-за push-уведомления.Вы можете проверить это> и обработать его соответствующим образом для своего приложения.т.е. отображать предупреждение, переходить> на страницу и т. д.
Однако у меня вопрос: как я могу это сделать в проекте Core, совместно используемом различными платформами?Я выполнил шаги, показанные в конце этой статьи в документации MvvmCross:
https://www.mvvmcross.com/documentation/advanced/customizing-appstart
Итак, мой код выглядит следующим образом:
App.cs
public class App : MvxApplication<object>
{
public override void Initialize()
{
CreatableTypes().EndingWith("Service").AsInterfaces().RegisterAsLazySingleton();
Mvx.IoCProvider.LazyConstructAndRegisterSingleton<IAppStartSynchronizer, AppStartSynchronizer>();
Mvx.IoCProvider.RegisterSingleton(() => UserDialogs.Instance);
RegisterCustomAppStart<HaasSohnAppStart<AppSyncViewModel>>();
}
public override object Startup(object parameter)
{
//never reached
Console.WriteLine("APP.CS STARTUP");
return base.Startup(parameter);
}
}
Пользовательский AppStart
public class HaasSohnAppStart<AppSyncViewModel> : MvxAppStart<AppSyncViewModel, object> where AppSyncViewModel : IMvxViewModel<object>
{
public HaasSohnAppStart(IMvxApplication application, IMvxNavigationService navigationService) : base(application, navigationService){}
/// <summary>
/// Don't await the navigation to the first view model to be able to do async operations in the first <typeparamref name="AppSyncViewModel"/>
/// see: https://nicksnettravels.builttoroam.com/post/2018/04/19/MvvmCross-Initialize-method-on-the-first-view-model.aspx
/// see: https://stackoverflow.com/questions/49865041/mvvmcross-app-wont-start-after-upgrading-to-version-6-0
/// see: https://github.com/MvvmCross/MvvmCross/issues/2829
/// </summary>
/// <param name="hint">Hint.</param>
protected override Task NavigateToFirstViewModel(object hint)
{
//First of all configure app synchronously to have db connection, api urls, translations, etc configured
AppConfig.Initialize().GetAwaiter().GetResult();
NavigationService.Navigate<AppSyncViewModel, object>(hint);
return Task.CompletedTask;
}
protected override Task<object> ApplicationStartup(object hint = null)
{
//hint always null
Console.WriteLine($"APPSTART APPLICATION STARTUP HINT = {hint}");
return base.ApplicationStartup(hint);
}
}
Извлечение модели первого вида
public class AppSyncViewModel : BaseViewModel, IMvxViewModel<object>
{
private IAppStartSynchronizer _appSyncrhronizer;
private INetworkAvailable _networkAvailable;
private MainController _mainController = MainController.Instance;
override public string Title => Strings["AppSyncViewModel_Label_Title"];
public string SyncInfo { get; set; } = "AppSyncViewModel_Label_SyncInProgress".Translate();
private bool _comeFromPushNotification;
public AppSyncViewModel(IMvxNavigationService navigationService, IAppStartSynchronizer appSynchronizer, INetworkAvailable networkAvailable, IUserDialogs userDialogs) : base(navigationService, userDialogs)
{
_appSyncrhronizer = appSynchronizer;
_networkAvailable = networkAvailable;
}
public override async Task Initialize()
{
if (_appSyncrhronizer != null)
{
IsBusy = true;
_appSyncrhronizer.SyncFinish += Syncnronizer_SyncFinish;
await _appSyncrhronizer.StartupSync(_networkAvailable);
}
await base.Initialize();
}
public async void Syncnronizer_SyncFinish(object sender, System.EventArgs e)
{
if (_comeFromPushNotification)
{
await _userDialogs.AlertAsync("we come from push notification", "parameter");
}
}
public void Prepare(object parameter)
{
//parameter always null
_comeFromPushNotification = parameter != null ? true : false;
Console.WriteLine($"APPSYNCVIEWMODEL: parameter = {parameter}");
}
Я ожидал, что эта реализация получит некоторый параметр в параметре подсказки при запуске пользовательского приложениякласс в методе NavigateToFirstViewModel, а затем в методе prepare первой модели представления (AppSyncViewModel) установите флаг, чтобы узнать, открывали ли мы приложение из push-уведомления, в зависимости от этого параметра.
В результате получается, что параметр всегда равен нулю, даже если приложение закрыто и запускается из push-уведомления.
Итак, чтобы подвести итог моего вопроса, как я могу обнаружить, в проекте Core, использующем MvvmCross, чтобы приложение запускалось из push-уведомления?