Причина перехода моего приложения в приостановленное состояние? - PullRequest
0 голосов
/ 13 октября 2019

Я создал приложение ios для отслеживания местоположения (используя библиотеку CocoaLumberjack для записи файла журнала). Так что фоновое обновление местоположения включено и работает для моего тестирования (у меня почти до 8 часов в фоновом режиме). Когда приложение отправляется в магазин. В нашем приложении произошла большая проблема. Когда приложение перешло в фоновый режим, отслеживание местоположения не работает должным образом. Он не отправляет местоположение пользователя на сервер в течение некоторого периода времени. Таким образом, я получаю файл журнала от клиента и проверяю, есть ли разрыв во времени в файле журнала. Я часто получаю местоположение пользователя (каждую секунду). Таким образом, я думал, что приложение перешло в приостановленное состояние в момент возникновения разрыва в файле журнала? Почему приложение переходит в приостановленное состояние, даже если я часто получаю местоположение в фоновом режиме? есть ли причина для перехода приложения в состояние ожидания? искомый лот не может найти какие-либо действительные данные?

 func startTimer()
{
    if bgTimer == nil
    {
        bgTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.startLocationChanges), userInfo: nil, repeats: true)
    }
}

func stopTimer()
{
    if bgTimer != nil
    {
        bgTimer?.invalidate()
        bgTimer = nil
    }
}

@objc func startLocationChanges() {
    locationManager.delegate = self
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.pausesLocationUpdatesAutomatically = false
    locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
    locationManager.requestAlwaysAuthorization()
    locationManager.startUpdatingLocation()
}

func locationManager(_ manager: CLLocationManager,  didUpdateLocations locations: [CLLocation]) {
    //let lastLocation = locations.last!

    // Do something with the location.
    /*print(lastLocation)
    let logInfo = "BGLocationManager didUpdateLocations : " + "\(lastLocation)"
    AppDelegate.appDelegate().writeLoggerStatement(strInfo: logInfo)*/

    locationManager.stopUpdatingLocation()
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {

    if let error = error as? CLError, error.code == .denied {
        // Location updates are not authorized.
        manager.stopMonitoringSignificantLocationChanges()
        return
    }

    // Notify the user of any errors.
}



func applicationDidEnterBackground(_ application: UIApplication) {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationDidEnterBackground: when the user quits.
    self.writeLoggerStatement(strInfo: "applicationDidEnterBackground")
    appstate = "Background"

    if CoreDataUtils.isUserLoggedIn(entityName: "UserInfo") == true {
        let user = CoreDataUtils.fetchCurrentUser(entityName: "UserInfo")
        if user!.isGPSActive == "1"
        {
            if backgroundTaskIdentifier != nil
            {
                application.endBackgroundTask(backgroundTaskIdentifier!)
                backgroundTaskIdentifier = UIBackgroundTaskInvalid
            }

            backgroundTaskIdentifier = application.beginBackgroundTask(expirationHandler: {
                //UIApplication.shared.endBackgroundTask(self.backgroundTaskIdentifier!)
            })

            BGLocationManager.shared.startTimer()

            let logInfo = String(format:"applicationDidEnterBackground backgroundTimeRemaining : %f",(Double)(application.backgroundTimeRemaining / 60))
            self.writeLoggerStatement(strInfo: logInfo)
        }
    }
}

1 Ответ

2 голосов
/ 13 октября 2019

Несколько замечаний:

  1. Процесс beginBackgroundTask занимает всего 3 минуты, а не 8 часов. Он предназначен для того, чтобы позволить вам выполнить короткую задачу конечной длины, не оставляя приложение работать бесконечно. Хуже того, если вы не вызовете endBackgroundTask в обработчике завершения, приложение будет завершено бесцеремонно через 3 минуты, а не изящно приостановлено.

  2. Существует два основныхшаблоны для фоновых обновлений местоположения.

    • Если приложение представляет собой приложение для навигации, вы можете оставить приложение работающим в фоновом режиме. Но выполнение стандартных служб определения местоположения в фоновом режиме приведет к потере заряда батареи пользователя в течение нескольких часов. Таким образом, Apple разрешит это только в том случае, если ваше приложение действительно в этом нуждается (например, ваше приложение является актуальным навигационным приложением, а не просто приложением, которое по каким-либо причинам хочет отслеживать местоположения).

    • Другой шаблон служба значительных изменений . С помощью этой службы ваше приложение будет приостановлено, но ОС разбудит его для доставки обновлений местоположения, а затем позволит снова приостановить его. См. Обработка событий местоположения в фоновом режиме . Это не так точно, как в стандартных службах определения местоположения, но поскольку приложение не работает постоянно и поскольку ему не нужно раскручивать оборудование GPS, оно потребляет гораздо меньше энергии.

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

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

...