iOS applicationWillResignActive 任务在应用程序再次激活之前不会执行
iOS applicationWillResignActive task not performed until app becomes active again
我正在尝试使用 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 {
[=12=].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")
}
}
}
}
Apps moving to the background are expected to put themselves into a
quiescent state as quickly as possible so that they can be suspended
by the system. If your app is in the middle of a task and needs a
little extra time to complete that task, it can call the
beginBackgroundTaskWithName:expirationHandler: or
beginBackgroundTaskWithExpirationHandler: method of the UIApplication
object to request some additional execution time. Calling either of
these methods delays the suspension of your app temporarily, giving it
a little extra time to finish its work. Upon completion of that work,
your app must call the endBackgroundTask: method to let the system
know that it is finished and can be suspended.
所以,您在这里需要做的是在您的应用暂停时执行一个有限长度的任务。这将为您的应用赢得足够的时间将您的记录同步到服务器。
示例片段:
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
}
}
有关详细信息,请参阅此 article。
我正在尝试使用 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 {
[=12=].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")
}
}
}
}
Apps moving to the background are expected to put themselves into a quiescent state as quickly as possible so that they can be suspended by the system. If your app is in the middle of a task and needs a little extra time to complete that task, it can call the beginBackgroundTaskWithName:expirationHandler: or beginBackgroundTaskWithExpirationHandler: method of the UIApplication object to request some additional execution time. Calling either of these methods delays the suspension of your app temporarily, giving it a little extra time to finish its work. Upon completion of that work, your app must call the endBackgroundTask: method to let the system know that it is finished and can be suspended.
所以,您在这里需要做的是在您的应用暂停时执行一个有限长度的任务。这将为您的应用赢得足够的时间将您的记录同步到服务器。
示例片段:
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
}
}
有关详细信息,请参阅此 article。