首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在didReceiveRemoteNotification中异步下载

问在didReceiveRemoteNotification中异步下载
EN

Stack Overflow用户
提问于 2015-08-16 02:37:55
回答 3查看 2.4K关注 0票数 10

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

当然,所有这些都是在用户从未打开应用程序的情况下发生的。当他打开这个应用程序时,将会有一个新的数据等待。这是无声的回击:

代码语言:javascript
复制
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调用。试图把一些代码组合在一起。

EN

回答 3

Stack Overflow用户

发布于 2015-08-16 03:18:38

你没有正确地使用“completionHandler”

调用这个完成处理程序就像告诉iOS您已经完成了您的任务,现在它可以让您的应用程序重新进入睡眠状态或处于后台。你马上给我打电话

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

代码语言:javascript
复制
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的文档描述

下载操作完成后要执行的块。调用此块时,传入最能描述下载操作结果的fetch结果值。您必须调用这个处理程序,并且应该尽快这样做。有关可能值的列表,请参见UIBackgroundFetchResult类型。

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

票数 6
EN

Stack Overflow用户

发布于 2016-01-28 22:57:30

来增加这个答案。当我这样做的时候,当我在didReceiveRemoteNotification之后启动后台获取时,我得到了不稳定的支持。我可以启动一个阿拉莫火连接,但它可能无法工作,它将几乎立即死亡。

在浏览互联网和阅读无声通知教程时,似乎没有人提到使用:

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

每个人都说:

是的,每个文档有大约30秒的时间来完成您的工作,或者您需要使用NSURLSession后台会话。

在我自己的测试和拔毛中,为了给自己买到30秒,您可能需要调用UIApplicationDelegate上的beginBackgroundTask* + endBackgroundTask方法。

参考文献:

ref/occ/instm/UIApplication/beginBackgroundTaskWithName:expirationHandler

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

具体来说,apple dev论坛的答案是由Apple Developer Relations、Developer Technical、Core OS/Hardware的一位成员完成的

他特别指出:

哈?在NSURLSession共享会话中发出请求。这些请求只有在应用程序仍在运行时才能运行。如果应用程序再次被挂起,这通常是在这种情况下发生的情况,请求将在中途停止。你在这里有两个选择:

  • 继续使用共享会话,并使用UIApplication后台任务来防止应用程序挂起。重要的是,请求必须完全快速地工作,因为UIApplication后台任务通常只给您大约30秒的执行时间。
  • 在NSURLSession后台会话中运行请求,当请求完成后,该会话将组织恢复应用程序。

注意,第一个选项继续使用共享会话,并使用UIApplication后台任务来防止应用程序挂起.

票数 2
EN

Stack Overflow用户

发布于 2015-08-16 03:28:58

重写

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

后台会话中的AlamoFire下载

而完成处理程序应该在AF调用的完成块的末尾被调用,而不是在方法的开头。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32031320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档