Swift: 等待应用程序执行直到文件下载结束
Swift: wait for app execution till file downloads ends
我有个问题,我自己解决不了。但我认为必须有一个非常简单的解决方案。太简单了我看不到:-(
我有一个功能,可以从网络服务器下载文件并将其存储在设备上。此功能有效:
func downloadFile (fileOnServer: String, fileOnDevice: URL) async {
if let dataURL = URL(string: fileOnServer) {
URLSession.shared.downloadTask(with: dataURL) { (tempFileUrl, response, error) in
if let dataTempFileUrl = tempFileUrl {
do {
let urlData = try Data(contentsOf: dataTempFileUrl)
try urlData.write(to: fileOnDevice)
// checkSavedFile(file: fileOnDevice)
print("download successfull")
} catch {
print("Error")
}
}
}.resume()
}
}
我在一个简单的 SwiftUI 视图中调用这个函数:
truct UpdateView: View {
@State var text = "Loading"
var body: some View {
VStack{
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
Text(text)
}
.task()
{
print ("START downloadFile() ")
await downloadFile(fileOnServer: htmlLinkForJSON, fileOnDevice: downloadedJSON)
await downloadFile(fileOnServer: htmlLinkForCategories, fileOnDevice: downloadedCategories)
print ("END downloadFile()")
print ("---------")
print ("Start checkSavedFile()")
checkSavedFile(file: downloadedJSON)
checkSavedFile(file: downloadedCategories)
print ("END checkSavedFile()")
print ("---------")
}
}
}
现在我的问题是:正如您在控制台输出中看到的,checkSavedFile() 在下载结束之前启动。如何暂停我的代码直到下载结束?
你明白我的意思吗?
START downloadFile()
END downloadFile()
---------
Start checkSavedFile()
checkSavedFile gestartet
file:///Users/Library/Developer/CoreSimulator/Devices/AB464055-A554-4B4B-9AB3-BF7FAD670A81/data/Containers/Data/Application/7C940BA4-99EB-4250-83CB-BA6D2AA9669B/Documents/downloadedJSON.txt available!
checkSavedFile gestartet
file:///Users/Library/Developer/CoreSimulator/Devices/AB464055-A554-4B4B-9AB3-BF7FAD670A81/data/Containers/Data/Application/7C940BA4-99EB-4250-83CB-BA6D2AA9669B/Documents/downloadedCategories.txt available!
END checkSavedFile()
---------
2022-01-04 20:27:17.573376+0100 Blindzeln_Prototyp[4296:186653] [boringssl] boringssl_metrics_log_metric_block_invoke(151) Failed to log metrics
download successfull
download successfull
您必须通过使用适当的异步 URLSession
API 使 downloadFile
真正 async
。完成处理程序 API 没有 wait
.
func downloadFile (fileOnServer: String, fileOnDevice: URL) async throws {
guard let dataURL = URL(string: fileOnServer) else { throw URLError(.badURL) }
let (dataTempFileUrl, _) = try await URLSession.shared.download(from: dataURL)
try FileManager.default.moveItem(at: dataTempFileUrl, to: fileOnDevice)
}
在 task
中,您添加了一个 do - catch
块来处理错误
.task()
{
do {
print ("START downloadFile() ")
try await downloadFile(fileOnServer: htmlLinkForJSON, fileOnDevice: downloadedJSON)
try await downloadFile(fileOnServer: htmlLinkForCategories, fileOnDevice: downloadedCategories)
print ("END downloadFile()")
print ("---------")
print ("Start checkSavedFile()")
checkSavedFile(file: downloadedJSON)
checkSavedFile(file: downloadedCategories)
print ("END checkSavedFile()")
print ("---------")
} catch {
print(error)
}
}
我有个问题,我自己解决不了。但我认为必须有一个非常简单的解决方案。太简单了我看不到:-(
我有一个功能,可以从网络服务器下载文件并将其存储在设备上。此功能有效:
func downloadFile (fileOnServer: String, fileOnDevice: URL) async {
if let dataURL = URL(string: fileOnServer) {
URLSession.shared.downloadTask(with: dataURL) { (tempFileUrl, response, error) in
if let dataTempFileUrl = tempFileUrl {
do {
let urlData = try Data(contentsOf: dataTempFileUrl)
try urlData.write(to: fileOnDevice)
// checkSavedFile(file: fileOnDevice)
print("download successfull")
} catch {
print("Error")
}
}
}.resume()
}
}
我在一个简单的 SwiftUI 视图中调用这个函数:
truct UpdateView: View {
@State var text = "Loading"
var body: some View {
VStack{
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
Text(text)
}
.task()
{
print ("START downloadFile() ")
await downloadFile(fileOnServer: htmlLinkForJSON, fileOnDevice: downloadedJSON)
await downloadFile(fileOnServer: htmlLinkForCategories, fileOnDevice: downloadedCategories)
print ("END downloadFile()")
print ("---------")
print ("Start checkSavedFile()")
checkSavedFile(file: downloadedJSON)
checkSavedFile(file: downloadedCategories)
print ("END checkSavedFile()")
print ("---------")
}
}
}
现在我的问题是:正如您在控制台输出中看到的,checkSavedFile() 在下载结束之前启动。如何暂停我的代码直到下载结束? 你明白我的意思吗?
START downloadFile()
END downloadFile()
---------
Start checkSavedFile()
checkSavedFile gestartet
file:///Users/Library/Developer/CoreSimulator/Devices/AB464055-A554-4B4B-9AB3-BF7FAD670A81/data/Containers/Data/Application/7C940BA4-99EB-4250-83CB-BA6D2AA9669B/Documents/downloadedJSON.txt available!
checkSavedFile gestartet
file:///Users/Library/Developer/CoreSimulator/Devices/AB464055-A554-4B4B-9AB3-BF7FAD670A81/data/Containers/Data/Application/7C940BA4-99EB-4250-83CB-BA6D2AA9669B/Documents/downloadedCategories.txt available!
END checkSavedFile()
---------
2022-01-04 20:27:17.573376+0100 Blindzeln_Prototyp[4296:186653] [boringssl] boringssl_metrics_log_metric_block_invoke(151) Failed to log metrics
download successfull
download successfull
您必须通过使用适当的异步 URLSession
API 使 downloadFile
真正 async
。完成处理程序 API 没有 wait
.
func downloadFile (fileOnServer: String, fileOnDevice: URL) async throws {
guard let dataURL = URL(string: fileOnServer) else { throw URLError(.badURL) }
let (dataTempFileUrl, _) = try await URLSession.shared.download(from: dataURL)
try FileManager.default.moveItem(at: dataTempFileUrl, to: fileOnDevice)
}
在 task
中,您添加了一个 do - catch
块来处理错误
.task()
{
do {
print ("START downloadFile() ")
try await downloadFile(fileOnServer: htmlLinkForJSON, fileOnDevice: downloadedJSON)
try await downloadFile(fileOnServer: htmlLinkForCategories, fileOnDevice: downloadedCategories)
print ("END downloadFile()")
print ("---------")
print ("Start checkSavedFile()")
checkSavedFile(file: downloadedJSON)
checkSavedFile(file: downloadedCategories)
print ("END checkSavedFile()")
print ("---------")
} catch {
print(error)
}
}