在didReceiveRemoteNotification中进行异步下载

时间:2015-08-16 02:37:56

标签: 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)
    }
}

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

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

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

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

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

2 个答案:

答案 0 :(得分:1)

REWRITE

您没有正确使用AlamoFire,但您可以将其配置为在后台状态下进行抓取:

AlamoFire Download in Background Session

完成处理程序应该在AF调用的完成块结束时调用,而不是在方法的开头。

答案 1 :(得分:1)

添加到这个答案。当我这样做时,在didReceiveRemoteNotification之后启动后台提取时,我得到了不稳定的支持。我可以开始Alamofire连接,但它可能不起作用,它几乎会立即死亡。

搜索互联网并查看无声通知教程,似乎没有人提到使用:

  • beginBackgroundTaskWithExpirationHandler:
  • beginBackgroundTaskWithName(_:expirationHandler:)
  • endBackgroundTask(_:)

每个人都说:

  

是的,每个文档大约需要30秒才能完成工作,或者您需要使用NSURLSession后台会话

它出现在我自己的测试和拔毛中,为了给自己买 30秒,您可能需要调用beginBackgroundTask* + endBackgroundTask <上的UIApplicationDelegate方法/ p>

参考文献:

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/#//apple_ref/occ/instm/UIApplication/beginBackgroundTaskWithName:expirationHandler

https://forums.developer.apple.com/message/96731#96731

具体来说,apple dev论坛答案由Apple Developer Relations,开发者技术支持,核心操作系统/硬件的成员完成

他具体说:

  

咦?您在NSURLSession共享会话中发出请求。只要应用程序仍在运行,此类请求才会运行。如果应用程序再次被暂停,这通常是在这种情况下发生的情况,请求将中途停止。   你有两个选择:

     
      
  • 继续使用共享会话并使用UIApplication后台任务来阻止您的应用暂停。   重要信息要使此操作完成,请求必须完全快速,因为UIApplication后台任务通常只能为您提供大约30秒的执行时间。
  •   
  • 在NSURLSession后台会话中运行请求,该会话将在请求完成后组织恢复您的应用。
  •   

请注意第一个选项继续使用共享会话并使用UIApplication后台任务来阻止您的应用暂停。