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)
       }    
    }