我不清楚如何正确使用它,但看到其他人在做这类事情:
func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) {
manager.sharedInstance.backgroundCompletionHandler = completionHandler
}
在我们的类似实施中,此时completionHandler
为partial apply forwarder for reabstraction thunk helper...
其中manager
(尽管是单身人士)本质上是:
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.ourcompany.app")
let manager = Alamofire.Manager(configuration: configuration)
但是,这会导致在控制台中打印以下警告:
Warning: Application delegate received call to -application:handleEventsForBackgroundURLSession:completionHandler: but the completion handler was never called.
我设置了一个断点here,此时该消息已在控制台中显示,backgroundCompletionHandler
为nil
。
我们正在使用Xcode 7.0进行iOS 9 SDK构建,目前正在使用Alamofire 2.0.2
我最初认为这是在合并我们的Swift 2.0分支时引入的,但是我也看到了使用Xcode 6.4对iOS 8 SDK进行早期提交的消息。
更新1
解决@ cnoon的建议:
didSet
课程的backgroundCompletionHandler
上的Manager
内添加和打印时,会在之前记录警告。sessionDidFinishEventsForBackgroundURLSession
课程内的delegate
上设置为Manager
的封闭内部打印时,会在警告后打印。sessionDidFinishEventsForBackgroundURLSession
之前覆盖backgroundCompletionHandler
并在其内部打印时,会在>>警告后打印消息。我应该注意,当我尝试从手机上传一些屏幕截图时,我最初无法重现此问题,以便尝试这些建议。
只有在尝试分享一些照片之后我才能再次重现这一点。我不确定或不相关(如果有的话),但可能与上传时间较长的照片有关。
更新2
UIBackgroundModes
的设置与@Nick描述的完全相同,直接在completionHandler()
内调用application:handleEventsForBackgroundURLSession:completionHandler:
不会显示警告。
更新3
所以,我似乎忽略了一个小而重要的细节。 Alamofire.Manager
周围的包装器没有直接暴露它。其实施的相关部分如下所示:
private var manager: Manager
public var backgroundCompletionHandler: (() -> Void)? {
get {
return manager.backgroundCompletionHandler
}
set {
manager.backgroundCompletionHandler = backgroundCompletionHandler
}
}
并在AppDelegate
中设置完成处理程序执行该代码路径。
func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) {
myManager.sharedInstance.backgroundCompletionHandler = completionHandler
}
我已确认以下更改以公开Alamofire.Manager
的实例并直接访问它不会产生警告:
public var manager: Manager
// public var backgroundCompletionHandler: (() -> Void)? {
// get {
// return manager.backgroundCompletionHandler
// }
// set {
// manager.backgroundCompletionHandler = backgroundCompletionHandler
// }
// }
和AppDelegate
:
func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) {
myManager.sharedInstance.manager.backgroundCompletionHandler = completionHandler
}
基于此,似乎使用计算属性代理完成处理程序是问题的原因。
我真的不想公开这个属性,并且想知道任何变通方法或替代方案。
答案 0 :(得分:1)
看起来你正在做的一切都是正确的。我有一个示例应用程序,它完全按照您所描述的正常工作,并且不会抛出您看到的警告。我猜你在某处仍然有一些小错误。以下是一些尝试的想法:
didSet
课程的backgroundSessionHandler
上添加Manager
日志声明以验证其是否已设置sessionDidFinishEventsForBackgroundURLSession
中添加一条日志语句,以验证它是否按预期调用sessionDidFinishEventsForBackgroundURLSession
并手动调用backgroundSessionHandler
您的计算属性错误。相反,它需要将backgroundCompletionHandler
设置为newValue
。否则,您永远不会正确地将其设置为新值。有关详细信息,请参阅此thread。