Bumblebee18
Bumblebee18

Reputation: 53

Swift 5.5: Async/Await URLSession.shared.data() throws an error

I tried to make use of the new Async/Await features in Swift 5.5 and tried the following code

let url = URL(string: "http://itunes.apple.com/lookup?bundleId=\(id)&country=at")

let (data, _) = try await URLSession.shared.data(from: url!)

let resultStruct = try jsonDecoder.decode(ResponseStruct.self, from: data)

Every time I execute this, the try await URLSession.shared.data(from: url!) part throws an error. If I catch it and print error.localizedString, I always get "cancelled". This happens with all different kinds of URLs. I tried to stick to the tutorials I found online, but what am I missing here?

EDIT: I forced the app into a runtime exception to get more details of the error:

Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSURLErrorDomain Code=-999 "cancelled"

As this post explains NSURLErrorDomain error code -999 in iOS, this error occurs when the SSL certificate of the server has issues, which I don't think is the case, as I am accessing the iTunes server or when the request gets canceled by anything else in my app, which looks like to be the case for me.

Upvotes: 1

Views: 2234

Answers (2)

Niccolò Fontana
Niccolò Fontana

Reputation: 356

I encountered the same problem in a SwiftUI app. I was using the task view modifier to load data asynchronously and update the view based on the loading states.

As mentioned in the documentation:

If the task doesn’t finish before SwiftUI removes the view or the view changes identity, SwiftUI cancels the task.

If this is your case, make sure to update the UI only after the task completes.

Alternative solution

Alternatively you can use the onAppear view modifier (which doesn't cancel the Task) and run the task inside its body:

Color.clear.onAppear {
    Task {
        await viewModel.load()
    }
}

Upvotes: 4

Sulthan
Sulthan

Reputation: 130102

Change http to https. You cannot normally call insecure calls unless you add an exception to your Info.plist to disable App Transport Security.

There should be also a log from App Transport Security in your console.

Since ATS blocks the connection, the request gets cancelled.

See NSAppTransportSecurity for more info

Upvotes: 3

Related Questions