获取远程通知在后台运行的方法

时间:2017-09-06 08:56:05

标签: ios swift firebase apple-push-notifications firebase-notifications

我正在使用Firebase Messaging(通知)向iOS上的用户发送推送提醒。对于我的应用程序,这是一个todo应用程序,我正在使用Swift 3.当用户获得推送通知时,我希望他们能够通过推送通知完成任务。

一切都很有效。用户获得推动。当他们三维触摸时,他们会看到“完整按钮”。点击“完成按钮”后,应用程序中的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)
    })
}

在行动班:

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()        
    })
}

1 个答案:

答案 0 :(得分:1)

在调用userNotificationCenter()的runloop循环之后,您的应用程序基本上被暂停,因此如果您的完成处理程序是对异步工作的响应,那么在您的应用程序再次恢复之前,该工作将永远不会发生。为了解决这个问题,您可能需要在该函数内部开始后台任务,然后让完成处理程序在完成后结束后台任务。这告诉系统你需要在后台保持活力一段时间(虽然不能保证,如果你花了太长时间)

参见"执行有限限制任务"在这个URL(对不起,它的Obj-C,但应该有一个Swift方式来做):

https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html