Закрытое приложение запускает событие :didReceiveRemoteNotification:

Я создаю приложение для геолокации, и я хотел, чтобы автоматически запускался сервис, который каждый раз присылал мне координаты.

Глядя в инете прочитал, что технически это невозможно на ios, но есть некоторые способы побороть проблему.

Я хотел принять тихое уведомление.

Я реализовал метод, и когда приложение находится в фоновом режиме, все работает, но когда я включаю устройство и отправляю тихое уведомление, событие: didReceiveRemoteNotification: не срабатывает. или даже когда я закрываю приложение из переключателя приложений, а затем отправляю уведомление, оно не срабатывает.

Я хотел знать, если что-то не так, если вы можете это сделать.

ps: я использую: didReceiveRemoteNotification: и нет приложения: didReceiveRemoteNotification: fetchCompletionHandler: (может быть проблема в этом?)

Мой код в AppDelegate:

 public override async   void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> 
   completionHandler)
        {

             await Manager.SendPosition(completionHandler);
        }

в моем FinishedLaunching:

if (Convert.ToInt16(UIDevice.CurrentDevice.SystemVersion.Split('.')[0].ToString()) < 8)
            {
                UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | 
                UIRemoteNotificationType.Sound;
                UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
            }
            else
            {
                UIUserNotificationType notificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
                var settings = UIUserNotificationSettings.GetSettingsForTypes(notificationTypes, new NSSet(new string[] { }));
                UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
                UIApplication.SharedApplication.RegisterForRemoteNotifications();
            }

и в моем info.plist:

   <key>UIBackgroundModes</key>
      <array>
        <string>location</string>
        <string>remote-notification</string>
      </array>

ОБНОВИТЬ:

public async Task<bool> SendPosition(Action<UIBackgroundFetchResult> completionHandler = null)
        {
            StartLocationUpdates();
            var setting = ConnectDb()?.Table<Settings>().FirstOrDefault() ?? new Settings();
            _currentLong = 14.52538;
            _currentLat = 36.82842;
            if (_currentLong != 0 && _currentLat != 0)// && setting.TimeNotification != 0)
            {
                var objectSend = new
                {
                    unique_key = setting.UniqueKey, 
                    lat = _currentLat,
                    lng = _currentLong, 
                    idPlayerOneSignal = setting.IdPlayerOneSignal,
                    token = "" 
                };

                var client = new HttpClient { BaseAddress = new Uri("http://amywebservice.com/") };
                var data = JsonConvert.SerializeObject(objectSend);

                var content = new StringContent(data, Encoding.UTF8, "application/json");
                var response = await client.PostAsync("api/setPosition", content);
                if (response.IsSuccessStatusCode)
                {
                    var successResult = response.Content.ReadAsStringAsync().Result;
                    Debug.WriteLine("k", successResult);
                    if (completionHandler != null)
                    {
                        completionHandler(UIBackgroundFetchResult.NoData);
                    }
                    return true;
                }
                else
                {
                    var failureResulr = response.Content.ReadAsStringAsync().Result;
                    Debug.WriteLine("f", failureResulr);
                    if (completionHandler != null)
                    {
                        completionHandler(UIBackgroundFetchResult.NoData);
                    }
                    return false;
                }
            }
            return false;
        }

но не работает, если я отправляю тихое уведомление, я запускаю только первый полет и только если приложение находится в фоновом режиме.

Если я включу телефон и уведомлю, уведомление не будет работать.


person Bruno Mandarà    schedule 26.09.2017    source источник


Ответы (1)


  1. #P1# <цитата> #P2# #P3#
  2. #P4# <блочная цитата> #P5#
  3. Мне не очень понятно ваше описание включения устройства (разблокировать устройство без открытия приложения? или другое) здесь:

    но когда я включаю устройство и отправляю тихое уведомление

    Но согласно application(_:didReceiveRemoteNotification:fetchCompletionHandler:)

    Как только вы закончите обработку уведомления, вы должны вызвать блок в параметре обработчика, иначе ваше приложение будет закрыто. У вашего приложения есть до 30 секунд времени настенных часов для обработки уведомления и вызова указанного блока обработчика завершения. На практике вы должны вызвать блок обработчика, как только закончите обработку уведомления. Система отслеживает прошедшее время, энергопотребление и стоимость данных для фоновых загрузок вашего приложения. Приложения, потребляющие значительное количество энергии при обработке push-уведомлений, не всегда могут быть выведены из спящего режима для обработки будущих уведомлений.

    Вы должны реализовать completionHandler, когда закончите обработку уведомления.

    Добавьте completionHandler() в DidReceiveRemoteNotification в соответствующих местах, например, в операторе if:

    • completionHandler(UIBackgroundFetchResult.NewData) when you get what you want.
    • completionHandler(UIBackgroundFetchResult.Failed) при возникновении проблем с получением данных.
    • completionHandler(UIBackgroundFetchResult.NoData) когда нет данных.

    Похоже, в вашем коде это пропущено, что может повлиять на тихое уведомление.

person Kevin Li    schedule 27.09.2017
comment
спасибо за разъяснение, но теперь с кодом, который я разместил, если я выключу телефон, перезапущу его и отправлю тихое уведомление, я не смогу разбудить свое приложение. Это может быть для завершенияHandler, как мне выполнить операцию завершенияHandler? - person Bruno Mandarà; 28.09.2017
comment
похоже на это: public override async void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler) { completionHandler(UIBackgroundFetchResult.NoData); await Manager.SendPosition(); } ??? - person Bruno Mandarà; 28.09.2017
comment
@BrunoMandarà, выполните completionHandler, когда закончите отправлять позицию, например, в завершенном обратном вызове метода SendPosition(). - person Kevin Li; 29.09.2017