iOS applicationWillResignActive задача не выполняется, пока приложение снова не станет активным - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь использовать applicationWillResignActive() для синхронизации некоторых данных с моей базой данных Firestore до того, как приложение войдет в фоновый режим.

func applicationWillResignActive(_ application: UIApplication) {
        self.uploadWantToPlay()
}

Когда я вызываю функцию загрузки из applicationWillResignActive()он запускается, но данные не добавляются в Firestore до того, как в следующий раз приложение станет активным.

Когда я вместо этого запускаю ту же функцию из одного из моих ViewControllers, данные сразу добавляются в Firestore.

Я также пытался вызвать функцию из applicationDidEnterBackground(), я пытался запустить ее в ее собственной DispatchQueue.Но результат был тот же.

Как запустить эту функцию, когда пользователь собирается покинуть приложение и заставить его правильно выполнить синхронизацию базы данных?

Функции, обрабатывающие синхронизацию базы данных;

func uploadWantToPlay() {
    print ("Inside uploadWantToPlay")
    if let wantToPlay = User.active.wantToPlayList {
        if let listEntries = wantToPlay.list_entries {
            let cleanedEntries = listEntries.compactMap({ (entry: ListEntry) -> ListEntry? in
                if entry.game?.first_release_date != nil {
                    return entry
                } else {
                    return nil
                }
            })
            let gamesToUpload = cleanedEntries.filter {
                $0.game!.first_release_date! > Int64(NSDate().timeIntervalSince1970 * 1000)
            }
            DatabaseConnection().writeWantToPlayToDatabase(user: User.active,wantToPlay: gamesToUpload)
        }
    }
}

func writeWantToPlayToDatabase(user: User, wantToPlay: [ListEntry]) {
    firebaseSignIn()
    let deviceId = ["\(user.deviceId)": "Device ID"]
    for entry in wantToPlay {
        let wantToPlayGameRef = fireStore.collection(WANTTOPLAY).document("\(entry.game!.id!)")

        wantToPlayGameRef.updateData(deviceId) {(err) in
            if err != nil {
                wantToPlayGameRef.setData(deviceId) {(err) in
                    if let err = err {
                        Events().logException(withError: err, withMsg: "DatabaseConnection-writeWantToPlayToDatabase(user, [ListEntry]) Failed to write to database")
                    } else {
                        print("Document successfully written to WantToPlayGames")
                    }
                }
            } else {
                print("Document successfully updated in WantToPlayGames")
            }
        }
    }
}

1 Ответ

0 голосов
/ 05 июня 2018

Согласно документации Apple

Приложения, перемещающиеся в фоновый режим, должны как можно быстрее перевести себя в состояние покоя, чтобы система могла их приостановить.,Если ваше приложение находится в середине задачи и ему требуется немного дополнительного времени для ее выполнения, оно может вызвать beginBackgroundTaskWithName: expirationHandler: или beginBackgroundTaskWithExpirationHandler: метод объекта UIApplication, чтобы запросить дополнительное время выполнения.Вызов любого из этих методов временно приостанавливает приостановку работы вашего приложения, давая ему немного дополнительного времени для завершения работы.По завершении этой работы ваше приложение должно вызвать метод endBackgroundTask:, чтобы система знала, что она завершена и может быть приостановлена.

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

Пример кода:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var backgroundTask: UIBackgroundTaskIdentifier!

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        self.registerBackgroundTask()

        // Do your background work here
        print("Do your background work here")

        // end the task when work is completed
        self.endBackgroundTask()
    }

    func registerBackgroundTask() {
        self.backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
            self?.endBackgroundTask()
        }
        assert(self.backgroundTask != UIBackgroundTaskInvalid)
    }

    func endBackgroundTask() {
        print("Background task ended.")
        UIApplication.shared.endBackgroundTask(backgroundTask)
        backgroundTask = UIBackgroundTaskInvalid
    }

}

Для получения дополнительной информации см. Эту статью .

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