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,则无法继续下载,需要重新开始下载。 在连通性闭包中,只需要勾选isReachableisReachableOnEthernetOrWiFi参数即可。 在可达性检查中,如果您有 resumeData,则需要使用新的下载请求,如果没有,则需要使用全新的请求。

调用 response 闭包后,您将无法再次运行相同的下载请求。

我没有像你一样尝试在下载请求中使用suspendresume。文档似乎暗示可以使用suspendresume 来做你正在做的事情,但通常的做法是取消请求,然后使用简历数据创建一个新请求。您还必须在请求失败之前执行此操作,我认为这是不可能的。

我猜你的请求在调用可达性闭包时已经失败了。

希望这有助于您走上正轨。有关这些步骤的更多信息,我会参考 URL Loading System 文档以及 Alamofire README。

【讨论】:

问题是,当我关闭连接时,响应闭包直到很久以后才会调用,当它触发 超时错误。如果我在那段时间打开连接,回调最终会以相同的超时时间触发。我发现的方法是在检测到网络丢失时取消下载,保存resumeData,并在连接恢复后尝试使用保存的数据稍后恢复。 我观察到的另一件事是,如果用户终止应用程序,response callback 将不会被触发,即使我订阅UIApplicationWillTerminateNotification 取消下载以启动回调并将resumeData 保存到磁盘以在将来重新启动时恢复它。我也观察到有一些 CFNetworkDownload_*.tmp 文件,我想我也可以使用它们来恢复它,但我不知道如何获取那个 临时文件名,因为 destination callback 不是在下载完成之前不会触发。 我应该如何处理这种情况? UIApplicationWillTerminateNotification 不会在用户强制退出您的应用时调用,只有在系统退出时才会调用。如果您需要在应用处于后台或终止状态时处理下载,则需要考虑使用后台会话配置。 我正在使用 beginBackgroundTaskWithExpirationHandler 将 resumeData 保存到磁盘,并且在应用程序后台运行一段时间后它可以工作。问题是当我杀死应用程序时......那个过期处理程序没有被调用,所以我订阅了那个通知,它启动了一个 resumeData 为 nil 的方法(当时)所以我取消下载但响应回调不是' t火了,所以我不能保存它......

以上是关于Alamofire 恢复未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

jquery parseHTML 未按预期工作

Angular ngOnit () 未按预期工作

$() 函数未按预期工作

navigationController?.navigationBar.isUserInteractionEnabled 未按预期工作

libgdx ScissorStack 未按预期工作

UICollectionViewLayout 未按预期工作