0

我正在尝试在应用程序进入后台之前将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")
            }
        }
    }
}
4

1 回答 1

1

根据苹果文档

移至后台的应用程序应尽快将自身置于静止状态,以便系统暂停它们。如果您的应用程序正在执行任务并且需要一些额外的时间来完成该任务,它可以调用 UIApplication 对象的 beginBackgroundTaskWithName:expirationHandler: 或 beginBackgroundTaskWithExpirationHandler: 方法来请求一些额外的执行时间。调用这些方法中的任何一个都会暂时延迟您的应用程序的暂停,给它一点额外的时间来完成它的工作。完成这项工作后,您的应用程序必须调用 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
    }

}

有关详细信息,请参阅本文

于 2018-06-05T07:51:55.253 回答