ios - didReceiveRemoteNotification 中的异步下载

标签 ios ajax swift apple-push-notifications alamofire

我的应用配置为支持静默推送(内容可用),还支持后台获取。我需要实现的是在收到静默推送后,我需要向服务器发送 ajax 请求,取回数据并保存(使用 CoreData 保存)。

当然,所有这一切都是在用户没有打开应用程序的情况下发生的。当他打开应用程序时,将等待新的数据。这是静默推送回调:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {

    // Use Alamofire to make an ajax call:
    //...
    let mutableURLRequest = NSMutableURLRequest(URL: URL)
    let requestBodyData : NSMutableData = NSMutableData()

    mutableURLRequest.HTTPBody = body
    mutableURLRequest.HTTPMethod = "POST"
    mutableURLRequest.setValue("Bearer " + accessToken, forHTTPHeaderField: "Authorization")
    mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")

    request(mutableURLRequest)
        .responseJSON { (req, res, data, error) in

            //We do not reach this code block !

            // Save the incoming data to CoreData
            completionHandler(UIBackgroundFetchResult.NewData)
    }
}

现在的问题是,当通知到达并调用委托(delegate)时,ajax 代码会执行,调用服务器,然后退出。 ajax 回调中的代码不会运行。但是,当我打开应用程序并将其带到前台时,这段代码突然醒来并继续运行

这不是理想的行为,因为当我打开应用程序时,我仍然需要等待 1-2 秒才能运行这些操作(更新 UI 等)

我在这里做错了什么?我应该为此操作打开一个新的后台线程吗?

更新:
我将 completionHandler(UIBackgroundFetchResult.NewData) 移动到 ajax 回调中,但这仍然没有解决原始问题,即这个 ajax 回调代码块不会执行。

更新 2:
这似乎是 Alamofire 的问题,我将不得不使用 NSURLSession 来进行此 ajax 调用。尝试将一些代码放在一起。

最佳答案

您没有以正确的方式使用“completionHandler”

调用此完成处理程序就像告诉 iOS 您已完成任务,它现在可以让您的应用程序重新进入休眠状态或返回后台。你马上调用它

所以你只需要将你的代码改成这样

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    // Use Alamofire to make an ajax call:

    let mutableURLRequest = NSMutableURLRequest(URL: URL)
    let requestBodyData : NSMutableData = NSMutableData()

    mutableURLRequest.HTTPBody = body
    mutableURLRequest.HTTPMethod = "POST"
    mutableURLRequest.setValue("Bearer " + accessToken, forHTTPHeaderField: "Authorization")
    mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")

    request(mutableURLRequest)
        .responseJSON { (req, res, data, error) in
            // if there was an error then {
            //     completionHandler(UIBackgroundFetchResult.Failed)
            //     return
            // }

            // Save the incoming data to CoreData
            completionHandler(UIBackgroundFetchResult.NewData)
    }
}

这是 completionHandler 的 Apple 文档描述

The block to execute when the download operation is complete. When calling this block, pass in the fetch result value that best describes the results of your download operation. You must call this handler and should do so as soon as possible. For a list of possible values, see the UIBackgroundFetchResult type.

还有this answer可能会有帮助

关于ios - didReceiveRemoteNotification 中的异步下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32031320/

相关文章:

iphone - UITableview 部分标题不显示文本

ios - 如何在 Objective C 中重置计时器?

php - 妥善处理 "POST Content-Length of bytes exceeds the limit of"警告

swift - 当 isEnabled 为 false(禁用)时避免使 NSButton 透明/透明

ios - 我可以将自动续订订阅链接到应用程序帐户吗?

ios - 从二维码读取VCFCard?

javascript - ASP MVC Controller 发布具有不同值的相同 html 输入名称

jquery - 如何配置 ajax select2 以使用条形码扫描仪

ios - 为什么 UITextField 的文本属性在 Swift 2 中更改为可选?

swift - 完成 block 从不在 SKAction 组序列的末尾调用