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 ↗Code shown on screen · 7 snippets
Fetch photo with async/await
// 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
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
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
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
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
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
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
Related sessions
-
29 min -
14 min -
20 min -
34 min -
34 min