从远程通知在后台获取 运行 的方法
Getting method to run in the background from remote notification
我正在使用 Firebase Messaging(通知)向 iOS 上的用户发送推送提醒。对于我的应用程序,这是一个待办事项应用程序,我使用 Swift 3. 当用户收到推送通知时,我希望他们能够直接从推送通知完成任务。
几乎一切正常。用户得到推送。当他们使用 3d-touch 时,他们会看到 "complete button"。当点击 "complete button" 时,应用程序中的 didReceive 响应方法将在后台触发。
现在开始讨论问题, 在该方法中我使用了一个闭包,然后在该闭包中使用了一个闭包。由于某种原因,代码的第一部分在用户未打开应用程序的情况下在后台运行,但当用户再次打开应用程序时,最后一部分仅 运行(见下文)。这是为什么?
这是我的代码:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if response.actionIdentifier == notificationActionComplete, let actionKey = userInfo["actionKey"] as? String {
getAction(actionKey: actionKey, completion: { (action) in
action.complete {
}
})
}
completionHandler()
}
func getAction(actionKey: String, completion:@escaping (Action)->Void) {
Database.database().reference(withPath: "actions/\(actionKey)").observeSingleEvent(of: .value, with: { snapshot in
let action = Action(snapshot: snapshot)
completion(action)
})
}
正在行动class:
var ref: DatabaseReference?
init(snapshot: DataSnapshot) {
key = snapshot.key
ref = snapshot.ref
//Other inits here
}
func complete(completion:@escaping (Void) -> Void) {
//This code to remove the node is running fine in background
ref.removeValue { (error, ref) in
//The code in here is not running until the user opens the app next time
otherRef.updateChildValues(self.toAnyObject(), withCompletionBlock: { (error, ref) in
completion()
})
}
您的应用程序基本上在调用 userNotificationCenter() 的运行循环周期后挂起,因此如果您的完成处理程序响应异步工作,则该工作将永远不会发生,直到您的应用程序再次恢复。要解决这个问题,您可能需要在该函数内开始一个后台任务,然后让您的完成处理程序在完成时结束后台任务。这告诉系统你需要在后台存活一段时间(虽然不能保证,如果你花的时间太长)
请参阅 "Executing Finite Limit Tasks" URL(抱歉,它是 Obj-C,但也应该有 Swift 方法):
我正在使用 Firebase Messaging(通知)向 iOS 上的用户发送推送提醒。对于我的应用程序,这是一个待办事项应用程序,我使用 Swift 3. 当用户收到推送通知时,我希望他们能够直接从推送通知完成任务。
几乎一切正常。用户得到推送。当他们使用 3d-touch 时,他们会看到 "complete button"。当点击 "complete button" 时,应用程序中的 didReceive 响应方法将在后台触发。
现在开始讨论问题, 在该方法中我使用了一个闭包,然后在该闭包中使用了一个闭包。由于某种原因,代码的第一部分在用户未打开应用程序的情况下在后台运行,但当用户再次打开应用程序时,最后一部分仅 运行(见下文)。这是为什么?
这是我的代码:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if response.actionIdentifier == notificationActionComplete, let actionKey = userInfo["actionKey"] as? String {
getAction(actionKey: actionKey, completion: { (action) in
action.complete {
}
})
}
completionHandler()
}
func getAction(actionKey: String, completion:@escaping (Action)->Void) {
Database.database().reference(withPath: "actions/\(actionKey)").observeSingleEvent(of: .value, with: { snapshot in
let action = Action(snapshot: snapshot)
completion(action)
})
}
正在行动class:
var ref: DatabaseReference?
init(snapshot: DataSnapshot) {
key = snapshot.key
ref = snapshot.ref
//Other inits here
}
func complete(completion:@escaping (Void) -> Void) {
//This code to remove the node is running fine in background
ref.removeValue { (error, ref) in
//The code in here is not running until the user opens the app next time
otherRef.updateChildValues(self.toAnyObject(), withCompletionBlock: { (error, ref) in
completion()
})
}
您的应用程序基本上在调用 userNotificationCenter() 的运行循环周期后挂起,因此如果您的完成处理程序响应异步工作,则该工作将永远不会发生,直到您的应用程序再次恢复。要解决这个问题,您可能需要在该函数内开始一个后台任务,然后让您的完成处理程序在完成时结束后台任务。这告诉系统你需要在后台存活一段时间(虽然不能保证,如果你花的时间太长)
请参阅 "Executing Finite Limit Tasks" URL(抱歉,它是 Obj-C,但也应该有 Swift 方法):