简体   繁体   中英

Swift: 'Completion handler blocks are not supported in background sessions. Use a delegate instead.'

I am new to Swift and thus not very experienced. I do not know why this is not working.

I am trying to download a music file and then send it to the AVAudoPlayer to play.

Here is the code:

@IBAction func startDownload(_ sender: Any) {
    weak var weakSelf = self
    let url = URL(string: "http://www.noiseaddicts.com/samples_1w72b820/280.mp3")!
    let task = DownloadManager.shared.activate().downloadTask(with: url as URL, completionHandler: { (URL, response, error) -> Void in

        print("URL = \(URL)")

        weakSelf!.plays(url: URL! as URL)

    })
    task.resume()
}

and there error I am getting is:

DownloadTaskExample[31140:1527666] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Completion handler blocks are not supported in background sessions. Use a delegate instead.'

*** First throw call stack: ( 0 CoreFoundation 0x0000000110bbf34b exceptionPreprocess + 171 1 libobjc.A.dylib 0x000000010db2f21e objc_exception_throw + 48 2 CFNetwork 0x00000001111ada2c -[__NSURLBackgroundSession validateSerializabilityForRequest:completion:] + 172 3 CFNetwork 0x00000001111b035c -[__NSURLBackgroundSession _onqueue_downloadTaskForRequest:resumeData:completion:] + 36 4 CFNetwork 0x00000001111af37c __90-[__NSURLBackgroundSession downloadTaskForRequest:downloadFilePath:resumeData:completion:]_block_invoke + 38 5 CFNetwork 0x00000001111adddb __68-[__NSURLBackgroundSession performBlockOnQueueAndRethrowExceptions:]_block_invoke + 67 6 libdispatch.dylib 0x0000000111aa00cd _dispatch_client_callout + 8 7 libdispatch.dylib 0x0000000111a7d30a _dispatch_barrier_sync_f_invoke + 340 8 CFNetwork 0x00000001111add44 -[__NSURLBackgroundSession performBlockOnQueueAndRethrowExceptions:] + 174 9 CFNetwork 0x00000001111af2e5 -[__NSURLBackgroundSession downloadTaskForRequest:downloadFilePath: resumeData:completion:] + 243 10 DownloadTaskExample 0x000000010d54086d _TFC19DownloadTaskExample14ViewController13startDownloadfP_T_ + 525 11 DownloadTaskExample 0x000000010d540e33 _TToFC19DownloadTaskExample14ViewController13startDownloadfP_T_ + 67 12 UIKit 0x000000010e3685b8 -[UIApplication sendAction:to:from:forEvent:] + 83 13 UIKit 0x000000010e4ededd -[UIControl sendAction:to:forEvent:] + 67 14 UIKit 0x000000010e4ee1f6 -[UIControl _sendActionsForEvents:withEvent:] + 444 15 UIKit 0x000000010e4ed0f2 -[UIControl touchesEnded:withEvent:] + 668 16 UIKit 0x000000010e3d5ce1 -[UIWindow _sendTouchesForEvent:] + 2747 17 UIKit 0x000000010e3d73cf -[UIWindow sendEvent:] + 4011 18 UIKit 0x000000010e38463f -[UIApplication sendEvent:] + 371 19 UIKit 0x000000010eb7671d __dispatchPreprocessedEventFromEventQueue + 3248 20 UIKit 0x000000010eb6f3c7 __handleEventQueue + 4879 21 CoreFoundation 0x0000000110b64311 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17 22 CoreFoundation 0x0000000110 b4959c __CFRunLoopDoSources0 + 556 23 CoreFoundation 0x0000000110b48a86 __CFRunLoopRun + 918 24 CoreFoundation 0x0000000110b48494 CFRunLoopRunSpecific + 420 25 GraphicsServices 0x000000011444da6f GSEventRunModal + 161 26 UIKit 0x000000010e366964 UIApplicationMain + 159 27 DownloadTaskExample 0x000000010d54597f main + 111 28 libdyld.dylib 0x0000000111aec68d start + 1 29 ??? 0x0000000000000001 0x0 + 1 )

libc++abi.dylib: terminating with uncaught exception of type NSException

Please could someone help me so that Once the file is downloaded it is passed over to the plays function so I can play it :)

Ps Here is the DownloadManager I am using: https://www.ralfebert.de/snippets/ios/urlsession-background-downloads/

What this is telling you is that

  1. When you created your URLSession , you used a background configuration object, that is, with the background(withIdentifier:) method on URLSessionConfiguration .
  2. You started a download, with a completion block.
  3. This is not allowed.

The reason this isn't allowed is that with background downloads, your app might not be running when the download finishes, but iOS wants to wake up your app to tell it that the download finished. That completion block won't exist once your app stops running, so it's not an effective way of getting that notification.

You have a couple of options:

  • You can stop using a background session. Something like URLSessionConfiguration.default . No background downloads, though.
  • You can remove the callback and instead use methods declared in URLSessionDelegate to get the result of the download.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM