希望有人煽动,我们尝试在Apple论坛上发帖,但他们没有帮助。尝试找到检测用户取消的正确方法,使用 Swift 中的 AVAssetDownloadDelegate 从 AVAssetDownloadTask 对象下载/提取错误代码。我们尝试使用以下方法:
public func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL)
{
if let errorCode = assetDownloadTask.error?._code,
errorCode == NSURLErrorCancelled
{
do
{
try FileManager.default.removeItem(at: location)
}
catch
{
DDLogError("An error occurred trying to delete the contents on disk for (error)")
}
// if we do have a cancelled download and we have removed it, return before we save the location
return
}
// we need to save the location where the download finished, so when we call our delegate in
// urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
// we have a reference to it in order to pass along
self.locationDict[assetDownloadTask.urlAsset.url] = location
}
以及
public func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL)
{
if let error = assetDownloadTask.error as NSError?
{
switch (error.domain, error.code)
{
case (NSURLErrorDomain, NSURLErrorCancelled):
do
{
try FileManager.default.removeItem(at: location)
}
catch
{
DDLogError("An error occurred trying to delete the contents on disk for (error)")
}
// if we do have a cancelled download and we have removed it, return before we save the location
return
default:
DDLogError("An unexpected error occurred (error.domain)")
}
}
// we need to save the location where the download finished, so when we call our delegate in
// urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
// we have a reference to it in order to pass along
self.locationDict[assetDownloadTask.urlAsset.url] = location
}
但两者都出现在崩溃日志的 Crashlytics 中:
Crashed: com.-.ios.application.AssetDownloadUrlSession
0 libswiftFoundation.dylib 0x103afa01c specialized static URL._unconditionallyBridgeFromObjectiveC(_:) + 8344
1 Networking 0x1027d2178 $S13Networking26AssetDownloadUrlSessionC03urlE0_05assetC4Task22didFinishDownloadingToySo12NSURLSessionC_So07AVAssetcH0C10Foundation3URLVtFTf4dnnn_n + 456
2 Networking 0x1027ce3e8 $S13Networking26AssetDownloadUrlSessionC03urlE0_05assetC4Task22didFinishDownloadingToySo12NSURLSessionC_So07AVAssetcH0C10Foundation3URLVtFTo + 88
3 CFNetwork 0x1dc049c78 __89-[NSURLSession delegate_AVAssetDownloadTask:didFinishDownloadingToURL:completionHandler:]_block_invoke + 36
4 Foundation 0x1dc33c8bc __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 16
5 Foundation 0x1dc244ab8 -[NSBlockOperation main] + 72
6 Foundation 0x1dc243f8c -[__NSOperationInternal _start:] + 740
7 Foundation 0x1dc33e790 __NSOQSchedule_f + 272
8 libdispatch.dylib 0x1db2e56c8 _dispatch_call_block_and_release + 24
9 libdispatch.dylib 0x1db2e6484 _dispatch_client_callout + 16
10 libdispatch.dylib 0x1db28982c _dispatch_continuation_pop$VARIANT$mp + 412
11 libdispatch.dylib 0x1db288ef4 _dispatch_async_redirect_invoke + 600
12 libdispatch.dylib 0x1db295a18 _dispatch_root_queue_drain + 376
13 libdispatch.dylib 0x1db2962c0 _dispatch_worker_thread2 + 128
14 libsystem_pthread.dylib 0x1db4c917c _pthread_wqthread + 472
15 libsystem_pthread.dylib 0x1db4cbcec start_wqthread + 4
您可以实现此选项,它应该可以帮助您避免应用程序崩溃
func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) {
guard assetDownloadTask.urlAsset.assetCache?.isPlayableOffline == true,
assetDownloadTask.error == nil else { return }
locationDict[assetDownloadTask.urlAsset.url] = location
}
如果文件加载失败,为什么要尝试删除文件?
self.locationDict[assetDownloadTask.urlAsset.url] = location
我认为崩溃在这里[assetDownloadTask.urlAsset.url]在这种情况下,此值可能为零
面对同样的问题,事实证明 AVURLAsset 的 url
属性可以nil
,即使它没有定义为可选。这是一个丑陋但失败的可靠解决方法:
private extension AVURLAsset {
var isURLNil: Bool {
debugDescription.contains("URL = (null)")
}
}
显然,这可能会破坏 Swift 打印调试描述的方式(不太可能(未来的变化,但在此之前,他们可能还会修复框架中的这个错误。