ieg*_*j33 4 state download ios swift swiftui
我正在尝试使用 SwiftUI 组合一个杂志浏览应用程序,但在尝试创建下载进度指示器时遇到了障碍。我似乎无法找到一种方法来使ProgressBar
我从urlSession(didWriteData)
in进行更新URLSessionDownloadDelegate
。
我有一个DownloadManager
作为环境对象传递给主视图的单曲,它处理所有杂志问题的下载。
class DownloadManager: NSObject, URLSessionDownloadDelegate, ObservableObject {
var activeDownloads: [URL: Download] = [:]
lazy var downloadSession: URLSession = {
let config = URLSessionConfiguration.default
return URLSession(configuration: config, delegate: self, delegateQueue: nil)
}()
/*downloading and saving the issues is handled here*/
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
guard
let url = downloadTask.originalRequest?.url,
let download = activeDownloads[url]
else {
return
}
//this is the value that needs to be indicated by the UI
download.progress = (Float(totalBytesWritten) / Float(totalBytesExpectedToWrite))
}
}
Run Code Online (Sandbox Code Playgroud)
自定义Download
类包含以下内容:
class Download {
var issue: Issue
var url: URL
var progress: Float = 0.0
var task: URLSessionDownloadTask?
var resumeData: Data?
init(issue: Issue) {
self.issue = issue
self.url = issue.webLocation
}
}
Run Code Online (Sandbox Code Playgroud)
要下载的可用问题显示在 a 中的行中List
,并且在下载它们时,进度应该由ProgressBar
. 行布局代码的相关部分在这里:
struct IssueRow: View {
var issue: Issue
@EnvironmentObject var downloadManager: DownloadManager
@State var downloadProgress: Float = 0.0
var body: some View {
//the progress bar that needs to continuously update
ProgressBar(value: $downloadProgress)
.frame(height: 4)
}
private func downloadIssue() {
downloadManager.startDownload(issue: issue)
downloadProgress = downloadManager.activeDownloads[issue.webLocation]!.progress
//This does not actually change as the download progresses
}
Run Code Online (Sandbox Code Playgroud)
在内部ProgressBar
,进度存储为@Binding
浮点数。
struct ProgressBar: View {
@Binding var value: Float
var body: some View {
GeometryReader { geometry in
ZStack(alignment: .leading) {
Rectangle().frame(width: geometry.size.width, height:
geometry.size.height)
.opacity(0.3)
.foregroundColor(Color(UIColor.systemTeal))
Rectangle().frame(width: CGFloat(self.value)*geometry.size.width, height: geometry.size.height)
.foregroundColor(Color.navy)
.animation(.linear)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我真的不确定如何将 SwiftUI 的行为及其各种元素与 Swift 中的旧东西同步。任何帮助是极大的赞赏!
该方法是在您的下载中注入进度回调闭包并将其用作桥梁。
1) 在下载
class Download {
var issue: Issue
var url: URL
var callback: (Float) -> () // << here !!
var progress: Float = 0.0 {
didSet {
self.callback(progress) // << here !!
}
}
// ... other your code here ...
}
Run Code Online (Sandbox Code Playgroud)
2) 在 SwiftUI 中
private func downloadIssue() {
downloadManager.startDownload(issue: issue) { value in // << here !!
DispatchQueue.main.async {
self.downloadProgress = value // make sure on main queue
}
}
}
Run Code Online (Sandbox Code Playgroud)
3)在startDownload
(未提供)将回调闭包传递到创建的Download
实例中,例如(只是沙哑)
func startDownload(issue: Issue, progress: @escaping (Float) -> ()) {
let download = Download(issue: issue, url: issue.url, callback: progress)
...
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1005 次 |
最近记录: |