Как стать автором
Обновить

Комментарии 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()

Да, большое спасибо, недоглядел. Использование в таком виде allowDeferredLocationUpdates в принципе бесполезно было, по статье и коду убрал, текст дополнил.

У меня есть похожее приложение, но я умышленно не использую паузу, в итоге при использовании только significantChange и установке минимальных accuracy и distanceFilter приложение в списке пожирателей батареи не фигурирует вовсе либо изредка в пределах 1%. Но у меня цель записывать именно редкие точки достаточно отдаленные друг от друга.


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


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

Симуляция нужна только при дебаге, убедится что все работает как надо.
Про погрешность я уже писал, зато вспомнил благодаря комментарию о "авиарежиме", отсутствии симкарты и блокировке GPS, что дописал в "интересные моменты".

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории