#ios #swift
#iOS #swift
Вопрос:
Я создал приложение (Swift 4.0), которое, когда оно приближается к iBeacon, запускает локализацию startUpdatingLocation()
. Все работает отлично, как с приложением на переднем плане, в фоновом режиме, так и с убитым приложением. Но иногда местоположение не запускается. Похоже, что он никогда не вызывается locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
Я вошел во все: startUpdatingLocation
метод вызывается, и все настроено правильно.
Я пытался также использовать startMonitoringSignificantLocationChanges()
в сочетании с startUpdatingLocation()
: таким образом, локализация начинается после обратного вызова, который, предположительно, вызывается startMonitoringSignificantLocationChanges
(на самом деле первое обнаружение запускается более чем через 500 метров). Но даже этот трюк не всегда работает.
Я также пытался allowDeferredLocationUpdates(untilTraveled distance: CLLocationDistance, timeout: TimeInterval)
запустить локализацию, но ничего.
Я также пытался запустить локализацию асинхронно: она не разрешилась.
Я пытался использовать pausesLocationUpdatesAutomatically
как true, так и false: ничего.
locationManager(_ manager: CLLocationManager, didFailWithError error: Error)
Метод никогда не вызывается.
Ниже locationManager
приведен код конфигурации и метод активации локализации:
func configureLocationService() {
locationManager = CLLocationManager()
locationManager?.delegate = AppDelegate.shared
locationManager?.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager?.distanceFilter = Double(Configuration.getMinimumDistanceInMeters())
locationManager?.activityType = .fitness
locationManager?.pausesLocationUpdatesAutomatically = true
// locationManager?.pausesLocationUpdatesAutomatically = false
locationManager?.allowsBackgroundLocationUpdates = true
if #available(iOS 11.0, *) {
locationManager?.showsBackgroundLocationIndicator = true
} else {
// Fallback on earlier versions
}
locationManager?.requestAlwaysAuthorization()
}
...
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
if CLLocationManager.locationServicesEnabled() amp;amp; CLLocationManager.authorizationStatus() == .authorizedAlways {
manager.startMonitoringSignificantLocationChanges()
DispatchQueue.main.asyncAfter(deadline: .now() 2, execute: {
manager.stopMonitoringSignificantLocationChanges()
DispatchQueue.main.asyncAfter(deadline: .now() 1, execute: {
manager.startMonitoringSignificantLocationChanges()
manager.startUpdatingLocation()
UIApplication.shared.applicationIconBadgeNumber = 1
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.success)
}
}
}
}
Я делаю что-то не так? Есть способ ВСЕГДА активировать location с помощью startUpdatingLocation()?
Комментарии:
1. Привет, Матеуш, удалось ли вам решить проблему с тем, что startUpdatingLocation иногда не запускает обновления местоположения в фоновом режиме? У меня тоже такая же проблема, и я не смог найти решение. Очень признателен, если вы могли бы прокомментировать. Спасибо!
Ответ №1:
Если ваш код местоположения уже работает, проблема в другом месте.
Одной из распространенных ситуаций, вызывающих вашу проблему, является настройка вашего диспетчера местоположений в методе жизненного цикла контроллера представления, например viewDidLoad
или viewDidAppear
. Если приложение запускается в фоновом режиме (с холодного запуска, а не из приостановленного состояния), его контроллер представления никогда не будет отображаться, и методы жизненного цикла представления, такие как viewDidAppear
, никогда не будут вызываться.
Для устранения фоновых проблем с местоположением настройте свое приложение на отправку локального уведомления в определенные моменты (методы делегирования приложений, методы жизненного цикла контроллера просмотра, методы делегирования диспетчера местоположений), и вы сможете видеть, что происходит в режиме реального времени.
Комментарии:
1. Я уже использовал метод, аналогичный локальному уведомлению, для отладки (я добавил a
UIApplication.shared.applicationIconBadgeNumber = 1
в томAppDelegate
, гдеstartUpdatingLocation
выполняется): значок увеличивается, но локализация не активируется. ЗначениеlocationManager
устанавливаетсяappDelegate
в методеapplication (_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
2. Хорошо, тогда, возможно, вы установили
pausesLocationUpdatesAutomatically
значениеtrue
. Меняет ли значение false значение false?3. Я попытался
pausesLocationUpdatesAutomatically
true
просто попытаться решить проблему (изначально она была установлена наfalse
)4. Тогда я бы сказал, попробуйте разместить локальные уведомления в нескольких местах, чтобы отслеживать, что делает приложение. Узнайте, действительно ли вы переходите ко второму
Dispatch.main
вызову. Я не очень хорошо разбираюсь в GCD, но может ли это вложение привести к тупиковой ситуации?