Alamofire 恢复未按预期工作
Posted
技术标签:
【中文标题】Alamofire 恢复未按预期工作【英文标题】:Alamofire resume not working as expected 【发布时间】:2016-09-01 17:49:52 【问题描述】:我正在尝试下载一个文件,我想使用NetworkReachabilityManager
检测它何时失去连接,如下所示:
self.reachabilityManager?.listener = status in
print("Status: \(status)")
if status == .NotReachable
self.download?.suspend()
else if status == .Reachable(.EthernetOrWiFi)
self.download?.resume()
self.reachabilityManager?.startListening()
一开始我是这样开始下载的:
self.download = self.manager.download(.GET, url) (temporaryURL, response) -> NSURL in
return NSURL(string: fullFilename)!
.progress (bytesRead, totalBytesRead, totalBytesExpectedToRead) in
self.setProgress(totalBytesRead, totalBytesExpectedToRead: totalBytesExpectedToRead)
.response (request, response, data, error) in
self.handleDownloadResponse(fullFilename, response: response, data: data, error: error)
当我关闭网络时,我会认为self.download?.suspend()
会暂停下载请求,然后self.download?.resume()
会重新开始下载,但从不调用进度处理程序,并且过了一会儿响应处理程序会启动出现超时错误
我应该采取不同的做法吗?如何实现此行为(恢复网络后继续下载)?
【问题讨论】:
【参考方案1】:您需要对此逻辑进行大量更改,才能按预期工作。下面是一组步骤,可助您到达目的地。
-
当您与正在进行的请求失去连接时,您的
response
闭包将被调用,error
将指示连接问题。
在response
闭包中,如果data
参数不是nil
,则为下载请求的resumeData
,可用于从中断处继续下载。
如果data
参数为nil
,则无法继续下载,需要重新开始下载。
在连通性闭包中,只需要勾选isReachable
或isReachableOnEthernetOrWiFi
参数即可。
在可达性检查中,如果您有 resumeData
,则需要使用新的下载请求,如果没有,则需要使用全新的请求。
调用
response
闭包后,您将无法再次运行相同的下载请求。
我没有像你一样尝试在下载请求中使用suspend
和resume
。文档似乎暗示可以使用suspend
和resume
来做你正在做的事情,但通常的做法是取消请求,然后使用简历数据创建一个新请求。您还必须在请求失败之前执行此操作,我认为这是不可能的。
我猜你的请求在调用可达性闭包时已经失败了。
希望这有助于您走上正轨。有关这些步骤的更多信息,我会参考 URL Loading System 文档以及 Alamofire README。
【讨论】:
问题是,当我关闭连接时,响应闭包直到很久以后才会调用,当它触发 超时错误。如果我在那段时间打开连接,回调最终会以相同的超时时间触发。我发现的方法是在检测到网络丢失时取消下载,保存resumeData
,并在连接恢复后尝试使用保存的数据稍后恢复。
我观察到的另一件事是,如果用户终止应用程序,response callback
将不会被触发,即使我订阅UIApplicationWillTerminateNotification
取消下载以启动回调并将resumeData
保存到磁盘以在将来重新启动时恢复它。我也观察到有一些 CFNetworkDownload_*.tmp
文件,我想我也可以使用它们来恢复它,但我不知道如何获取那个 临时文件名,因为 destination callback
不是在下载完成之前不会触发。 我应该如何处理这种情况?
UIApplicationWillTerminateNotification
不会在用户强制退出您的应用时调用,只有在系统退出时才会调用。如果您需要在应用处于后台或终止状态时处理下载,则需要考虑使用后台会话配置。
我正在使用 beginBackgroundTaskWithExpirationHandler
将 resumeData 保存到磁盘,并且在应用程序后台运行一段时间后它可以工作。问题是当我杀死应用程序时......那个过期处理程序没有被调用,所以我订阅了那个通知,它启动了一个 resumeData 为 nil 的方法(当时)所以我取消下载但响应回调不是' t火了,所以我不能保存它......以上是关于Alamofire 恢复未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章
navigationController?.navigationBar.isUserInteractionEnabled 未按预期工作