Комментарии 11
Подскажите как правильно реализовать следующую задачу — необходимо получать геопозицию 1-2 раза в день, проверять, что пользователь находится в том же городе или уже в другом, и если переехал — показать push или local уведомление.
SignificantLocationChanges — проверяет изменение геопозиции каждые 5 — 15 минут, мне кажется это лишнее.
Я рассматриваю возможность отправки пушей с флагом content-available для того чтобы изредка будить приложение и в фоне проверять геопозицию. Будет ли работать такая схема?
У нас был опыт подобного рода, и простые silent-пуши не решили проблему, так как, начиная с iOS 7, пуши не приходят, если приложение было убито пользователем. Мы попытались извратиться и написать следующий костыль: вместо обычных silent-пушей, отправлять voip-пуш. В этом случае всё работает клёво, но Apple не пропустит такое приложение в стор, по крайней мере без IP-звонков. У нас они всё равно стояли в плановых фичах, поэтому вот делаем. Для Вас вряд ли такое решение актуально, но решил обсудить наболевшую тему.
Еще бы подробнее про GPX файлы. Я так понял, что после запуска приложения, система начинает «проигрывать» файл но не понятно:
Как задается скорость движения между точками?
CLLocationManager будет реагировать на точки или возможно срабатывание и в промежутках (в зависимости от настроек самого менеджера)?
Про скорость вот тут можно глянуть.
Provide one or more waypoints containing a latitude/longitude pair. If you provide one waypoint, Xcode will simulate that specific location. If you provide multiple waypoints, Xcode will simulate a route visitng each waypoint.
Optionally provide a time element for each waypoint. Xcode will interpolate movement at a rate of speed based on the time elapsed between each waypoint. If you do not provide a time element, then Xcode will use a fixed rate of speed. Waypoints must be sorted by time in ascending order.
Про точки и промежутки не понял вопроса, метод вызывается когда новые данные появились (обычно в массиве 1 элемент, но к примеру при использовании `defer` в массиве все точки что накопились)
func allowDeferredLocationUpdates(untilTraveled distance: CLLocationDistance, timeout: TimeInterval)
В документации в описании к нему указано:
Start the delivery of location updates before calling this method. The most common place to call this method is in your delegate’s locationManager(_:didUpdateLocations:) method.
В Вашем примере метод вызывается до старта получения локации и не в колбеке
locationManager(_:didUpdateLocations:)
Также отсутствует locationManager(_:didFinishDeferredUpdatesWithError:)
. Это сделано умышленно?Код писался с максимально простотой, по этому отсутствует обработка ошибок в принципе didFailWithError / didFinishDeferredUpdatesWithError (CLError.h).
Про то что allowDeferredLocationUpdates вызывается до didUpdateLocations:
Start the delivery of location updates before calling this method.
Соблюдено, CLLocationManager уже запущен. didUpdateLocations это не старт менеджера, первый вызов метода может быть и спустя пару минут, что наблюдал на практике.
Другое дело, что обычно allowDeferredLocationUpdates вызывается из didUpdateLocations, потому что в документации дальше следует:
After processing any new locations, call this method if you want to defer future updates until the distance or time criteria are met.
p.s. большое спасибо за комментарий, попутно вспомнил и поправил в статье, что я забыл о нюансах allowDeferredLocationUpdates и выпилил использование из примера ибо влиять в том использовании не должно было.
p.p.s. статью писал почти через 9 месяцев "не работы" с геолокацией, немного подзабыть успел, надеюсь никому не навредил "бесполезным" куском кода.
func start() {
setActiveMode(true)
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
motionManager.startActivityUpdates(to: .main, withHandler: { [weak self] activity in
self?.setActiveMode(activity?.cycling ?? false)
})
}
В функции setActiveMode(true) выставляется allowDeferredLocationUpdates и только потом стартует получение локации locationManager.startUpdatingLocation()
У меня есть похожее приложение, но я умышленно не использую паузу, в итоге при использовании только significantChange
и установке минимальных accuracy и distanceFilter
приложение в списке пожирателей батареи не фигурирует вовсе либо изредка в пределах 1%. Но у меня цель записывать именно редкие точки достаточно отдаленные друг от друга.
Очень важный пункт про погрешность. В самом начале работы с геосервисами было очень удивительно видеть трек мечущейся, в пределах довольно обширной области, точки, потому что уведомление о смене локации приходит даже если телефон лежит на столе и особенно если в помещении.
А вот проверять приложение вживую очень рекомендую так как симуляция трека слишком чистая и хорошая, а в реальности все совсем иначе — облака, перепрыгивание между вышками сотовой связи, отсутствие сотового сигнала и много других нюансов.
Работа с геолокацией в iOS 24/7