Фоновая служба определения местоположения перестает работать в течение определенного периода времени. - PullRequest
0 голосов
/ 28 сентября 2018

Я разрабатываю приложение для iOS, чтобы пользователи могли сохранять свой маршрут путешествия на сервер (публикуя свои местоположения через API).Проблема, с которой я борюсь, состоит в том, что несколько пользователей сообщили, что маршрут, который они сохранили, прерывается в середине поездки.Подробно, когда пользователи просматривают свой сохраненный маршрут на карте, часть маршрута представляет собой просто прямую линию, потому что местоположения этого участка маршрута не отправляются на сервер или просто потому, что устройство не может получать местоположения в это время.Странно то, что оставшаяся часть маршрута была записана нормально, поэтому похоже, что служба определения местоположения перестала работать на определенный период времени, но после этого она снова запустилась, и мое приложение смогло записать ее нормально.

И самое неприятноеявляется то, что я не могу воспроизвести эту проблему.

Вот обстоятельства проблемы, о которых сообщил пользователь:
- Пользователь запустил приложение, затем заблокировал экран устройства и положил его в карман, они его не трогали ввсе путешествиеНе произошло разряда батареи или сбоя.
- После проезда 8-9 км и все работало нормально, запись маршрута была прервана в следующие ~ 65 км, а затем снова хорошо записана в остальных ~ 80 км.

Ниже приведены настройки моего проекта:
- Фоновые режимы в ON в возможностях с обновлениями местоположения.
- Местоположения, полученные от службы определения местоположения, фильтруются на основе метки времени и точности и сохраняются в базовых данных с пометкой «isSent», если местоположение успешно отправляется на сервер.Таким образом, мое приложение может покрыть случай, когда сетевое соединение не работает.
- Места, помеченные ложным флагом «isSent», будут отправляться на сервер каждые 30 секунд.

Мой код LocationManager:

class LocationManager: NSObject, CLLocationManagerDelegate {

    var locationManager: CLLocationManager = {
        var _locationManager = CLLocationManager()
        _locationManager.delegate = self
        _locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
        _locationManager.activityType = .automotiveNavigation
        _locationManager.allowsBackgroundLocationUpdates = true
        _locationManager.pausesLocationUpdatesAutomatically = false

        return _locationManager
    }()


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

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        var positionsToSavedToDb: [DbPositionModel] = []

        for location in locations {
            let howRecent = location.timestamp.timeIntervalSinceNow

            guard abs(location.timestamp.timeIntervalSinceNow) < 10 && location.horizontalAccuracy > 0 && location.horizontalAccuracy < 33 else {
                continue
            }

            if self.locations.count > 0 {
                let distanceSinceLastLocation = location.distance(from: self.locations.last!)
                let timeSinceLastLocation = location.timestamp.timeIntervalSince(self.locations.last!.timestamp)
                if (distanceSinceLastLocation < 5 && abs(timeSinceLastLocation) < 10) {
                    continue
                }
            }

            // Create DbPositionModel from location and append to positionsToSavedToDb
        }

        // Save positionsToSavedToDb to core data
    }

    @objc func each30Seconds(_ timer: Timer) {
        // Select in database DbPositionModel objects with false “isSent” flag to send to server
    }
}

Можете ли вы, ребята, помочь мне обнаружить черные дыры в моем коде или что-нибудь, что я могу сделать, чтобы воспроизвести / исправить эту проблему?Большое спасибо !!!

1 Ответ

0 голосов
/ 01 октября 2018

Ваша установка выглядит хорошо для меняВсего один вопрос.Когда вы говорите, что он не работал на 60 км, а затем он начал работать на 80 км, это все было в фоновом режиме?Я имею в виду, что пользователю не нужно было вводить передний план, чтобы он снова начал работать, не так ли?

Ваш предел для location.horizontalAccuracy составляет 33. Вы думаете, что он будет очень точным.Я не уверен, возможно, устройство / город - плохая комбинация, и тогда вы возвращаетесь рано.Я предлагаю вам записать причину , почему вы выходите рано .Их город может отличаться от вашего.Также я слышал, что GPS iPhoneX, хотя и имеет правильное местоположение, возвращает horizontalAccuracy большое число.Это происходит в основном для пользователей iPhoneX?

enum LocationAccuracyError: Error {
    case stale(secondsOld: Double)
    case invalid
    case lowAccuracy(metersOff: Double)
}

extension LocationAccuracyError: LocalizedError{
    var errorDescription: String? {
        switch self {
        case .stale(let seconds):
            return NSLocalizedString("location was stale by: \(seconds) seconds", comment: "")
        case .invalid:
            return NSLocalizedString("location was invalid)", comment: "")
        case .lowAccuracy(let metersOff):
            return NSLocalizedString("location's horizontal Accuracy was off by likely more than: \(metersOff) meters" , comment: "")
        }
    }
}

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

private func checkLocationAccuracy(from location: CLLocation) throws {

    let ageOfLocation = -location.timestamp.timeIntervalSinceNow

    if ageOfLocation >= maximumAcceptedStale {
        throw LocationAccuracyError.stale(secondsOld: ageOfLocation)
    }

    if location.horizontalAccuracy <= 0 {
        throw LocationAccuracyError.invalid
    }

    if location.horizontalAccuracy > MaximumAcceptedHorizontalAccuracy{
        throw LocationAccuracyError.lowAccuracy(metersOff: location.horizontalAccuracy)
    }
}

Ваше конечное использование будет выглядеть следующим образом:

do {
       try checkLocationAccuracy(from: location)

   } catch let error {
       writelog("Bad Location: \(error.localizedDescription)")
   }

Я также добавил бы журналы вокруг состояния вашего приложения, например, добавив журнал для захвата didEnterBackground

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...