Home > Net >  Swift: wait for app execution till file downloads ends
Swift: wait for app execution till file downloads ends

Time:01-05

I have a problem, I can't solve by myself. But I think there has to be a very simple solution. So simple I can't see it :-(

I have a function that's downloads a file from a webserver and stores it on the device. this function works:

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

I call this function in a simple SwiftUI view:

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

Now my problem: As you can see on the console output the checkSavedFile() starts before the download ends. How can I pause my code till the downloads ends? Do you know what I mean?

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

CodePudding user response:

You have to make downloadFile really async by using the appropriate async URLSession API. The completion handler API doesn't wait.

enum URLError : Error {
    case badURL
}

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

In the task you have add a do - catch block to handle the error(s)

.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)
       }    
    }
  •  Tags:  
  • Related