Фоновый мониторинг местоположения iOS Swift

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

Я использую startUpdatingLocation () из CLLocationManager, и все работает нормально, пока приложение не проработает в фоновом режиме около 15 минут.

Затем приложение, кажется, закрывается, и отслеживание прекращается.

Я знаю, что это непрерывное отслеживание (например, MapMyRun) должно работать, но не знаю, как это сделать.

Обновлено: LocationManager настроен следующим образом

self.locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation
self.locationManager?.distanceFilter = kCLDistanceFilterNone
self.locationManager?.allowsBackgroundLocationUpdates = true
self.locationManager?.pausesLocationUpdatesAutomatically = false
self.locationManager?.activityType = CLActivityType.automotiveNavigation
self.locationManager?.showsBackgroundLocationIndicator = true

Добро пожаловать в Stack Overflow. Вы должны отредактировать свой вопрос, чтобы показать соответствующий код (например, как вы настраиваете свой менеджер местоположения), чтобы мы могли вам помочь.

Paulw11 06.09.2018 10:21

Какие фоновые режимы указаны в вашем info.plist?

Ashley Mills 06.09.2018 10:24

@ Paulw11 внесены правки. В их приложении. Выглядит здесь немного шатко.

Jared Barden 06.09.2018 10:37

@AshleyMills просто «местоположение»

Jared Barden 06.09.2018 10:40

Вам нужно установить allowBackgroundLocationUpdates на true

Paulw11 06.09.2018 10:51

@ Paulw11 Я думаю, что помнил, и забыл упомянуть, но я дважды проверю. Спасибо за твою помощь!

Jared Barden 06.09.2018 10:53

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

Paulw11 06.09.2018 10:53

@ Paulw11 Я снова отредактирую. Спасибо.

Jared Barden 06.09.2018 10:54

@ Paulw11 Я добавил дополнительный код.

Jared Barden 06.09.2018 11:09

Где вы выполняете этот код? Какая функция?

Paulw11 06.09.2018 11:14

@ Paulw11 У меня есть кнопка «Пуск», которая вызывает функцию для настройки диспетчера местоположения и запуска обновлений. Он находится в одном из моих контроллеров просмотра. Не в appdelegate, если это поможет.

Jared Barden 06.09.2018 11:15

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

Paulw11 06.09.2018 11:16

@ Paulw11 о! Где тогда хорошее место?

Jared Barden 06.09.2018 11:17

Делегат вашего приложения - хорошее место, поскольку он существует, пока существует ваше приложение, и на него легко ссылаться. Какую работу вы выполняете в качестве делегата вашего местоположения? Если вы выполняете слишком долго в фоновом режиме, iOS завершит работу вашего приложения.

Paulw11 06.09.2018 11:18

@ Paulw11 Я сохраняю данные о местоположении в таблице SQLLite и отправляю их в службу REST при наличии сетевого подключения. Происходит примерно каждые две секунды. Примерно до 15 минут в фоновом режиме, а затем он просто прекращается.

Jared Barden 06.09.2018 11:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
15
1 244
4

Ответы 4

Проверить

CLLocationManager.startMonitoringSignificantLocationChanges()

Документация Apple здесь

Проблема со значительным мониторингом местоположения в том, что мне нужна очень подробная информация. Это снимается каждые 500 метров или около того.

Jared Barden 06.09.2018 10:27

Идея ответа заключалась в том, что ваше приложение все еще работает в фоновом режиме, поэтому вы можете продолжать отслеживать местоположение. Мы делали это в iOS 9 и проверяли местоположение пользователя каждые полминуты или около того, и приложение было доступно в AppStore. Не уверен, что что-то изменилось в последнее время.

S2dent 08.09.2018 16:08

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

Согласно документации Apple относительно фоновых служб определения местоположения:

Enabling this mode does not prevent the system from suspending the app, but it does tell the system that it should wake up the app whenever there is new location data to deliver. Thus, this key effectively lets the app run in the background to process location updates whenever they occur.

Для получения дополнительной информации обратитесь к Фоновое выполнение

Должен быть какой-то способ. Такие приложения, как Google Карты, не закрываются, как то, что я вижу.

Jared Barden 06.09.2018 10:51

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

Если вы этого не сделаете, приложение прекратит работу в фоновом режиме по прошествии X времени, которое ОС сочтет подходящим.

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

BG Modes

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

Надеюсь, это поможет!

Привет, Джаред, вы уверены, что приложение не вылетает в фоновом режиме через 15 минут? Есть ли у вас какие-либо системы отчетов о сбоях, которые позволяют это отслеживать? Что-то вроде Crashlytics может помочь вам узнать, происходят ли сбои. Также может помочь, если вы разместите где-нибудь весь свой код, чтобы посмотреть и помочь. И последнее: проверьте, не использует ли ваше приложение из-за локального сохранения вашего местоположения слишком много ресурсов ЦП и памяти и не закрывается ли ОС по этой причине.

George Bafaloukas 06.09.2018 11:47

Я использую TestFlight и не вижу журналов сбоев. Как узнать, какой уровень использования ЦП и памяти слишком высок?

Jared Barden 06.09.2018 11:49

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

George Bafaloukas 06.09.2018 11:52

Я посмотрю на них. Спасибо!

Jared Barden 06.09.2018 11:55

iOS убивает службу определения местоположения в фоновом режиме. Вам нужно установить его вручную в настройках iPhone.

To enable access, tap Settings > Location and select Always"

Вы можете показать оповещение, чтобы проинформировать пользователя и перейти к настройкам.

func checkUsersLocationServicesAuthorization(){
        /// Check if user has authorized Total Plus to use Location Services
        if CLLocationManager.locationServicesEnabled() {
            switch CLLocationManager.authorizationStatus() {
            case .notDetermined:
                // Request when-in-use authorization initially
                // This is the first and the ONLY time you will be able to ask the user for permission
                self.locationManager.delegate = self
                locationManager.requestWhenInUseAuthorization()
                break

            case .restricted, .denied:
                // Disable location features
                let alert = UIAlertController(title: "Allow Location Access", message: "MyApp needs access to your location. Turn on Location Services in your device settings.", preferredStyle: UIAlertController.Style.alert)

                // Button to Open Settings
                alert.addAction(UIAlertAction(title: "Settings", style: UIAlertAction.Style.default, handler: { action in
                    guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
                        return
                    }
                    if UIApplication.shared.canOpenURL(settingsUrl) {
                        UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                            print("Settings opened: \(success)")
                        })
                    }
                }))
                alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil))
                self.present(alert, animated: true, completion: nil)

                break

            case .authorizedWhenInUse, .authorizedAlways:
                // Enable features that require location services here.
                let alert = UIAlertController(title: "Allow Location Access", message: "Lookout does not have access to your location while in the background. To enable access, tap Settings > Location and select Always", preferredStyle: UIAlertController.Style.alert)

                // Button to Open Settings
                alert.addAction(UIAlertAction(title: "Settings", style: UIAlertAction.Style.default, handler: { action in
                    guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
                        return
                    }
                    if UIApplication.shared.canOpenURL(settingsUrl) {
                        UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                            print("Settings opened: \(success)")
                        })
                    }
                }))
                alert.addAction(UIAlertAction(title: "Not Now", style: UIAlertAction.Style.default, handler: nil))
                self.present(alert, animated: true, completion: nil)

                break
            }
        }
    }

Для большей точности вызовите и этот метод

func startLocationService(){
    locationManager.startUpdatingLocation()
    locationManager.startMonitoringSignificantLocationChanges()
    locationManager.pausesLocationUpdatesAutomatically = false
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.showsBackgroundLocationIndicator = true
}

And don't forget to enable Background Modes in Target -> signing and capabilites

последняя проверка - добавить разрешение в info.plist

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

Другие вопросы по теме