我不清楚如何正确使用它,但见过其他人在做这种事情:
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.
我在这里设置了一个断点,此时消息已经在控制台中可见并且backgroundCompletionHandler
是nil
.
我们正在使用 Xcode 7.0 构建 iOS 9 SDK,目前使用 Alamofire 2.0.2
我最初认为这是在我们合并 Swift 2.0 分支时引入的,但我也看到了使用 Xcode 6.4 针对 iOS 8 SDK 进行早期提交的消息。
更新 1
解决@cnoon 的建议:
- 标识符匹配 - 配置和管理器设置在单例中,因此不可能出错。
- 在类中添加和打印
didSet
on时,会在警告之前记录该消息。backgroundCompletionHandler
Manager
- 当在类内部打印闭包
sessionDidFinishEventsForBackgroundURLSession
的delegate
内部时,在警告之后Manager
打印消息。 sessionDidFinishEventsForBackgroundURLSession
在调用之前覆盖并在其中打印时,将在警告之后backgroundCompletionHandler
打印消息。- 至于验证我是否为后台会话正确设置了 Xcode 项目,我不确定如何执行此操作,也找不到任何有关如何执行此操作的文档。
我应该注意,当尝试从我的手机上传一些屏幕截图时,我最初无法重现此问题以尝试这些建议。
只有在尝试分享一些照片后,我才能再次复制它。我不确定或相关性(如果有的话),但它可能与照片上传时间较长有关。
更新 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
}
基于此,似乎使用计算属性来代理完成处理程序是问题的原因。
我真的不想公开这个属性,并且很想知道任何解决方法或替代方法。