【问题标题】:Getting method to run in the background from remote notification从远程通知获取在后台运行的方法
【发布时间】:2018-02-14 16:27:16
【问题描述】:

我正在使用 Firebase 消息(通知)向 iOS 用户发送推送提醒。对于我的应用程序,这是一个待办事项应用程序,我使用的是 Swift 3。当用户收到推送通知时,我希望他们能够直接从推送通知中完成任务。

一切都很好。用户得到推送。当他们 3d-touch 时,他们会看到“完成按钮”。当点击“完成按钮”时,应用程序中的 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()        
    })
}

【问题讨论】:

  • 程序在到达未运行的代码时是否完全停止,或者只是跳过它并到达userNotificationCenter(_:didReceiveResponse)中的最后一个completionHandler()
  • 你能更新你的问题并显示getAction的声明吗?
  • ref 是什么?以及如何删除节点?
  • 您必须检查应用程序状态。您必须运行 2 个代码块,一个用于前台,另一个用于后台。
  • 代码似乎有点奇怪:完成后底部的completionHandler 将是对操作系统代码的回调。所以我通常在完成所有工作后调用它。如果您触发(延迟)代码(在其他自定义完成处理程序中......),您必须传递它并在最后一段代码中执行它。 (否则你告诉 iOS:“我完成了”,它认为你的任务完成了。

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


【解决方案1】:

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

请参阅此 URL 上的“执行有限限制任务”(抱歉,它是 Obj-C,但也应该有一种 Swift 的方式来做到这一点):

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多