#ios #swift #http-live-streaming #avassetdownloadtask
#iOS #swift #http-прямая трансляция #avassetdownloadtask
Вопрос:
надеясь, что у кого-то есть какие-то подсказки, мы попытались опубликовать их на форумах Apple, но они не помогли. Пытаюсь найти правильный способ обнаружения отмененной пользователем загрузки / извлечь код ошибки из объекта AVAssetDownloadTask с использованием AVAssetDownloadDelegate в Swift. Мы попытались использовать следующий метод:
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
Комментарии:
1. есть решение для этого?
Ответ №1:
Вы можете реализовать эту опцию, это должно помочь вам избежать сбоя приложения
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
}
Ответ №2:
Почему вы пытаетесь удалить файл, если он не загрузился?
self.locationDict[assetDownloadTask.urlAsset.url] = местоположение
Я думаю, что сбой здесь [assetDownloadTask.urlAsset.url] В этом случае это значение может быть равно нулю
Комментарии:
1. Мы не удаляем загрузку, если она не загрузилась, мы удаляем только в том случае, если пользователь явно отменяет / удаляет содержимое во время его загрузки, в чем и заключается вся проблема. Чтобы определить, что пользователь отменил его, нам нужно получить код ошибки, приведя ошибку к NSError и проверив, равно ли оно NSURLErrorCancelled
2. И если вы заметили журнал сбоев, он не выходит из строя из-за того, что в словарь вставлено значение nil, сбой:
specialized static URL._unconditionallyBridgeFromObjectiveC(_:)
3. Эта ошибка означает, что вы получили какое-то необязательное значение или пытаетесь присвоить необязательное значение значению obj c.
4. Странно, свойство urlAsset AVAssetDownloadTask является AVURLAsset, а не необязательным. И свойство url набора urlAsset — это тип URL, который также не является необязательным. Я думаю, поскольку я не могу безопасно развернуть их как дополнительные, я проверю, что они не равны нулю другим способом. Спасибо
Ответ №3:
Сталкиваюсь с той же проблемой, так что, оказывается, url
свойство AVURLAsset может быть nil
, даже если оно не определено как необязательное. Вот уродливое, но безотказное решение для этого:
private extension AVURLAsset {
var isURLNil: Bool {
debugDescription.contains("URL = (null)")
}
}
Очевидно, что это может привести к (маловероятным) будущим изменениям в том, как Swift печатает описания отладки, но до тех пор они, вероятно, также исправят эту ошибку во фреймворке.