如何解决在 swift ui 应用程序中在 iOS 14 上下载背景 mp3
我正在创建一个 swift UI 广播流应用程序,其中包含可以下载的过去剧集库。我希望用户能够开始下载然后锁定屏幕。目前,这会暂停正在进行的下载。我的下载功能:
func downloadFile(withUrl url: URL,andFilePath filePath: URL) {
URLSession.shared
.downloadTaskPublisher(for: url)
.retry(4)
.map(\.0)
.receive(on: RunLoop.main)
.sink(receiveCompletion: { [self] _ in
downloading = false
downloaded = true
},receiveValue: { data in
do {
self.downloading = true
try FileManager.default.moveItem(atPath: data.path,toPath: filePath.path)
} catch {
self.downloaded = false
print("Error: \(error.localizedDescription)")
print("an error happened while downloading or saving the file")
}
})
.store(in: &networkSubscription)
}
.downloadTaskPublisher(for: url)
在哪里:
import Combine
import Foundation
public extension URLSession {
/// Returns a publisher that wraps a URL session download task for a given
/// URL.
///
/// - Parameter url: The URL for which to create a download task.
/// - Returns: A publisher that wraps a download task for the URL.
func downloadTaskPublisher(for url: URL) -> DownloadTaskPublisher {
DownloadTaskPublisher(session: self,request: URLRequest(url: url))
}
/// Returns a publisher that wraps a URL session download task for a given
/// URL request.
///
/// - Parameter request: The URL request for which to create a download task.
/// - Returns: A publisher that wraps a download task for the URL request.
func downloadTaskPublisher(for request: URLRequest) -> DownloadTaskPublisher {
DownloadTaskPublisher(session: self,request: request)
}
}
public struct DownloadTaskPublisher {
fileprivate let session: URLSession
fileprivate let request: URLRequest
}
extension DownloadTaskPublisher: Publisher {
public typealias Output = (URL,URLResponse)
public typealias Failure = Error
public func receive<Subscriber>(subscriber: Subscriber)
where
Subscriber: Combine.Subscriber,Subscriber.Failure == Failure,Subscriber.Input == Output
{
let subscription = Subscription(subscriber: subscriber,session: session,request: request)
subscriber.receive(subscription: subscription)
}
}
private extension DownloadTaskPublisher {
final class Subscription {
private let downloadTask: URLSessionDownloadTask
init<Subscriber>(subscriber: Subscriber,session: URLSession,request: URLRequest)
where
Subscriber: Combine.Subscriber,Subscriber.Input == Output,Subscriber.Failure == Failure
{
downloadTask = session.downloadTask(with: request,completionHandler: { url,response,error in
guard let url = url,let response = response else {
subscriber.receive(completion: .failure(error!))
return
}
_ = subscriber.receive((url,response))
subscriber.receive(completion: .finished)
})
}
}
}
extension DownloadTaskPublisher.Subscription: Subscription {
fileprivate func request(_: Subscribers.Demand) {
downloadTask.resume()
}
fileprivate func cancel() {
downloadTask.cancel()
}
}
此下载功能会将剧集写入磁盘,但会在应用暂停时取消。
我想写一些类似的东西
func downloadFile(withUrl url: URL,andFilePath filePath: URL) {
URLSession.init(configuration: URLSessionConfiguration.background(withIdentifier: "background.download.session"))
.downloadTaskPublisher(for: url)
.retry(4)
.map(\.0)
.receive(on: RunLoop.main)
.sink(receiveCompletion: { [self] _ in
downloading = false
downloaded = true
},toPath: filePath.path)
} catch {
self.downloaded = false
print("Error: \(error.localizedDescription)")
print("an error happened while downloading or saving the file")
}
})
.store(in: &networkSubscription)
}
但是,这会引发运行时异常:libc++abi.dylib: terminating with uncaught exception of type NSException *** Terminating app due to uncaught exception 'NSGenericException',reason: 'Completion handler blocks are not supported in background sessions. Use a delegate instead.' terminating with uncaught exception of type NSException
我想使用组合成语在后台下载文件,避免将 AppDelegate
附加到我的 @main struct: App
。
解决方法
据我了解编译器抛出的错误,我很确定您需要像这样激活背景模式:
我确实找到了 raywenderlich.com 的详细教程,该教程几乎完全遵循您的用例。也许它可以帮助您更深入地了解此功能 ?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。