我的应用程序配置为支持静默推送(内容可用),还支持后台获取。我需要实现的是在收到一个无声的推送后,我需要向服务器发送一个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调用。试图把一些代码组合在一起。
发布于 2015-08-16 03:18:38
你没有正确地使用“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的文档描述
下载操作完成后要执行的块。调用此块时,传入最能描述下载操作结果的fetch结果值。您必须调用这个处理程序,并且应该尽快这样做。有关可能值的列表,请参见UIBackgroundFetchResult类型。
而且这个答案也可能会有帮助
发布于 2016-01-28 22:57:30
来增加这个答案。当我这样做的时候,当我在didReceiveRemoteNotification之后启动后台获取时,我得到了不稳定的支持。我可以启动一个阿拉莫火连接,但它可能无法工作,它将几乎立即死亡。
在浏览互联网和阅读无声通知教程时,似乎没有人提到使用:
每个人都说:
是的,每个文档有大约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后台任务来防止应用程序挂起.
发布于 2015-08-16 03:28:58
https://stackoverflow.com/questions/32031320
复制相似问题