Динамические локальные уведомления на основе Swift iOS

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

Однако мне сложно получить информацию, а затем отправить уведомление.

Вот мой код:

    var bgTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier()

    bgTask = UIApplication.shared().beginBackgroundTask {

        self.webService?.getStopEstimates(routeStopIds: stopRouteIdSet, routeNameDict: routeNameDict, completion: { (result) in

            if result == "error" {
                return
            }

            let notification = UILocalNotification()
            notification.fireDate = Date(timeIntervalSinceNow: 1)
            notification.alertTitle = region.identifier + " Stop Details"
            notification.alertBody = result
            notification.soundName = UILocalNotificationDefaultSoundName
            UIApplication.shared().scheduleLocalNotification(notification)
        })

        UIApplication.shared().endBackgroundTask(bgTask)
    }

Кто-нибудь может понять, почему он не может быть отправлен? Я включил службы фоновой выборки и определения местоположения. Это находится внутри didEnterRegion

Ответ 1

Я сделал то же самое (когда пользователь подходит к магазину со скидкой, он/она будет уведомлен).

Прежде всего, я бы предложил вам загрузить все данные и сохранить их в Core Data или SQLite, если это вариант.

Вторые взглянуть на значительное изменение местоположения здесь. Он обновит ваше местоположение в фоновом режиме каждые 500 метров, если вы двигаетесь, и это сэкономит много батареек, а не didUpdateLocation.

В-третьих, после использования SLC в каждом вызове извлеките из своих основных данных или SQLite 20 ближайших местоположений вашего текущего местоположения и добавьте их для мониторинга (используйте Haversine, чтобы рассчитать все точки на расстоянии от вашего текущего местоположения, а затем получить 20 ближайших). Каждый раз, когда SCL называется обновлением, регионы, которые вы контролируете (если сохранение ваших данных в автономном режиме не является вариантом, я бы рекомендовал отправить запрос на ваш веб-сервис здесь. Идеальный сценарий заключается в том, что вы отправите свое местоположение в свой веб-сервис, и он ответит назад с ближайшими точками, затем добавьте их для мониторинга)

При вызове didEnterRegion убедитесь, что ваши данные загружены, а затем создайте локальное уведомление.

Сообщите мне, если вам нужна дополнительная информация

PS. Имейте в виду, что ваше приложение может быть прекращено (в фоновом режиме) системой, если потребляет много ресурсов. В этом случае вам нужно повторно инициализировать все, что вам нужно для вытягивания и отображения данных (запросы в сети, менеджер местоположений и т.д.). Вы можете обнаружить, что приложение перезапущено из-за события местоположения в AppDelegate didFinisingLaunchingWithOptions:

  if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {}

Ответ 2

проверьте этот пример на GitHub, потому что я думаю, что ваша проблема здесь в том, как вы обрабатываете фоновое задание. Если вызов веб-службы занял слишком много времени, фоновая задача будет признана недействительной. Я не знаю, насколько хорошо вы знаете ObjC, но в приведенном выше примере вы найдете для него метод BackgroundTaskManager.

Вы должны убедиться, что:

  • Фоновая выборка в настройках цели (раздел "Режимы фона" ) ON.
  • Вы запросили и получили разрешение "всегда" (в plist)
  • Обновления местоположения в целевых настройках (раздел "Режимы фона" ) включены.
  • Зарегистрировано для уведомлений пользователей в appDidFinishLaunching в делетете приложения.
  • Заменить устаревшие фоновые задачи, если служба заняла слишком много времени.

В случае вызова startUpdatingLocation, когда ваше приложение находится в фоновом режиме, CoreLocation по-прежнему отвечает, запустив обновления местоположения для вашего приложения, но система больше не будет хранить для вас утверждение, и ваше приложение будет приостановлено один раз затраченное время в фоновом режиме. Это время (в настоящее время) составляет 10 секунд. Но на самом деле ваше приложение теперь приостановлено и больше не может получать обновления. Существует способ продлить эту продолжительность до (в настоящее время) до 3 минут, используя beginBackgroundTaskWithExpirationHandler: узнать больше об этом в документации Apple CoreLocation

Будет ли это достаточно продолжительное время, будет зависеть от вашего приложения.

Для вашего случая использования служба значительного изменения местоположения довольно эффективна. Вы можете начать обновление местоположения, когда ваше приложение находится на переднем плане, и отложите обновления местоположения, пока ваше приложение находится в фоновом режиме. Вы можете также прочитать документацию Apple о существенном изменении местоположения