在didReceiveRemoteNotification中进行异步下载

Yar*_*evi 10 ajax apple-push-notifications ios swift 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,问题是当通知到达并且调用委托时,执行ajax代码,调用服务器,然后退出.ajax回调中的代码不会运行.但是,当我打开应用程序并将其带到前台时,突然此代码部分唤醒并继续运行.

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

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

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

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

dGa*_*bit 6

你没有以正确的方式使用'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)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是Apple文档描述 completionHandler

下载操作完成时要执行的块.调用此块时,传入最能描述下载操作结果的获取结果值.您必须调用此处理程序,并应尽快执行此操作.有关可能值的列表,请参阅UIBackgroundFetchResult类型.

而且这个答案可能会有所帮助