Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2021 SwiftSystem Services

WWDC21 · 14 min · Swift / System Services

Use async/await with URLSession

Discover how you can adopt Swift concurrency in URLSession using async/await and AsyncSequence, and how you can apply Swift concurrency concepts to improve your networking code.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 7 snippets

Fetch photo with async/await swift · at 2:52 ↗
// Fetch photo with async/await

func fetchPhoto(url: URL) async throws -> UIImage
{
    let (data, response) = try await URLSession.shared.data(from: url)

    guard let httpResponse = response as? HTTPURLResponse,
          httpResponse.statusCode == 200 else {
        throw WoofError.invalidServerResponse
    }

    guard let image = UIImage(data: data) else {
        throw WoofError.unsupportedImage
    }

    return image
}
URLSession.data swift · at 3:45 ↗
let (data, response) = try await URLSession.shared.data(from: url)
guard let httpResponse = response as? HTTPURLResponse,
      httpResponse.statusCode == 200 /* OK */ else {
    throw MyNetworkingError.invalidServerResponse
}
URLSession.upload swift · at 4:03 ↗
var request = URLRequest(url: url)
request.httpMethod = "POST"

let (data, response) = try await URLSession.shared.upload(for: request, fromFile: fileURL)
guard let httpResponse = response as? HTTPURLResponse,
      httpResponse.statusCode == 201 /* Created */ else {
    throw MyNetworkingError.invalidServerResponse
}
URLSession.download swift · at 4:21 ↗
let (location, response) = try await URLSession.shared.download(from: url)
guard let httpResponse = response as? HTTPURLResponse,
      httpResponse.statusCode == 200 /* OK */ else {
    throw MyNetworkingError.invalidServerResponse
}

try FileManager.default.moveItem(at: location, to: newLocation)
Cancellation swift · at 4:44 ↗
let task = Task {
    let (data1, response1) = try await URLSession.shared.data(from: url1)

    let (data2, response2) = try await URLSession.shared.data(from: url2)

}

task.cancel()
asyncSequence demo swift · at 7:53 ↗
let (bytes, response) = try await URLSession.shared.bytes(from: Self.eventStreamURL)
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
    throw WoofError.invalidServerResponse
}
for try await line in bytes.lines {
    let photoMetadata = try JSONDecoder().decode(PhotoMetadata.self, from: Data(line.utf8))
    await updateFavoriteCount(with: photoMetadata)
}
task specific delegate demo swift · at 11:20 ↗
class AuthenticationDelegate: NSObject, URLSessionTaskDelegate {
    private let signInController: SignInController
    
    init(signInController: SignInController) {
        self.signInController = signInController
    }
    
    func urlSession(_ session: URLSession,
                    task: URLSessionTask,
                    didReceive challenge: URLAuthenticationChallenge) async
    -> (URLSession.AuthChallengeDisposition, URLCredential?) {
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic {
            do {
                let (username, password) = try await signInController.promptForCredential()
                return (.useCredential,
                        URLCredential(user: username, password: password, persistence: .forSession))
            } catch {
                return (.cancelAuthenticationChallenge, nil)
            }
        } else {
            return (.performDefaultHandling, nil)
        }
    }
}

Resources