SlideShare a Scribd company logo
async/await in Swi!
Photo by Stephen H on Unsplash
Peter Friese | Firebase Developer Advocate | @pete!riese
let req = URLRequest(url: URL(string: “https:!"yourapi/path“)!)
let task = URLSession.shared.dataTask(with: req) { data, response, error in
!" do stuff once data arrives
}
task.resume()
Asynchronous code is everywhere
completion handler
func process(url: String, completion: @escaping (Article) !# Void) {
self.fetchArticle(from: url) { html in
self.extractTitle(from: html) { title in
self.extractText(from: html) { text in
self.extractImage(from: url) { imageUrl in
self.inferTags(from: text) { tags in
let article = Article(url: url,
title: title,
tags: tags,
imageUrlString: imageUrl)
completion(article)
}
}
}
}
}
}
A more complex example
extension ArticleAnalyser {
func process(url: String, completion: @escaping (Article) !# Void) {
self.fetchArticle(from: url) { result in
switch result {
case .failure(let error):
print(error.localizedDescription)
case .success(let html):
self.extractTitle(from: html) { result in
switch result {
case .failure(let error):
print(error.localizedDescription)
case .success(let title):
self.extractText(from: html) { result in
switch result {
case .failure(let error):
print(error.localizedDescription)
case .success(let text):
Let’s add some error handling…
!
extension AsyncArticleAnalyser {
func process(url: String) async throws !# Article {
let htmlText = try await fetchArticle(from: url)
let text = try await extractText(from: htmlText)
let title = try await extractTitle(from: htmlText)
let imageUrl = try await extractImage(from: url)
let tags = await inferTags(from: text)
return Article(url: url,
title: title,
tags: tags,
imageUrlString: imageUrl)
}
}
How about this?
Swift 5.5
This is just the toolchain, really
Select toolchain here
Toolchain is active
func helloWorld(name: String, completion: (String) !# Void) {
completion("Hello, (name)")
}
Let’s convert a callback-based function!
func greeting() {
helloWorld(name: "Peter") { result in
print(result)
}
}
func helloWorld(name: String, completion: (String) !# Void) {
completion("Hello, (name)")
}
Let’s convert a callback-based function!
func helloWorld(name: String) async !# String {
return "Hello, (name)"
}
Before
After
func helloWorld(name: String, completion: (String) !# Void) {
completion("Hello, (name)")
}
Let’s convert a callback-based function!
let result = await helloWorld(name: "Peter")
func helloWorld(name: String) async !# String {
return "Hello, (name)"
}
Before
After
Call site
Sometimes, it’s more complicated, though
func getUser(id: Int, _ completion: @escaping (User?) !# Void) {
let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!)
URLSession.shared.dataTask(with: req) { data, response, error in
guard let data = data else { return }
do {
let user = try JSONDecoder().decode(User.self, from: data)
completion(user)
} catch { completion(nil) }
}.resume()
}
func greeting() {
getUser(id: 1) { result in
if let userName = result!$name {
print("Hello, (userName)")
}
}
}
Sometimes, it’s more complicated, though
func getUser(id: Int, _ completion: @escaping (User?) !# Void) {
let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!)
URLSession.shared.dataTask(with: req) { data, response, error in
guard let data = data else { return }
do {
let user = try JSONDecoder().decode(User.self, from: data)
completion(user)
} catch { completion(nil) }
}.resume()
}
Let’s keep this entire function
func getUser(id: Int, _ completion: @escaping (User?) !# Void) { !!% }
func getUser(id: Int, _ completion: @escaping (User?) !# Void) {
let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!)
URLSession.shared.dataTask(with: req) { data, response, error in
guard let data = data else { return }
do {
let user = try JSONDecoder().decode(User.self, from: data)
completion(user)
} catch { completion(nil) }
}.resume()
}
Sometimes, it’s more complicated, though
func getUser(id: Int, _ completion: @escaping (User?) !# Void) { !!% }
func getUser(id: Int) async !# User? {
return await withCheckedContinuation { cont in
getUser(id: id) { result in
cont.resume(returning: result)
}
}
}
Introduce this wrapper
func getUser(id: Int, _ completion: @escaping (User?) !# Void) {
let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!)
URLSession.shared.dataTask(with: req) { data, response, error in
guard let data = data else { return }
do {
let user = try JSONDecoder().decode(User.self, from: data)
completion(user)
} catch { completion(nil) }
}.resume()
}
Sometimes, it’s more complicated, though
func getUser(id: Int, _ completion: @escaping (User?) !# Void) { !!% }
func getUser(id: Int) async !# User? {
return await withCheckedContinuation { cont in
getUser(id: id) { result in
cont.resume(returning: result)
}
}
}
Call the original here
func getUser(id: Int, _ completion: @escaping (User?) !# Void) {
let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!)
URLSession.shared.dataTask(with: req) { data, response, error in
guard let data = data else { return }
do {
let user = try JSONDecoder().decode(User.self, from: data)
completion(user)
} catch { completion(nil) }
}.resume()
}
Sometimes, it’s more complicated, though
func getUser(id: Int, _ completion: @escaping (User?) !# Void) { !!% }
func getUser(id: Int) async !# User? {
return await withCheckedContinuation { cont in
getUser(id: id) { result in
cont.resume(returning: result)
}
}
}
Create a continuation
Resume once we receive a result
func getUser(id: Int, _ completion: @escaping (User?) !# Void) {
let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!)
URLSession.shared.dataTask(with: req) { data, response, error in
guard let data = data else { return }
do {
let user = try JSONDecoder().decode(User.self, from: data)
completion(user)
} catch { completion(nil) }
}.resume()
}
Sometimes, it’s more complicated, though
func getUser(id: Int, _ completion: @escaping (User?) !# Void) { !!% }
func getUser(id: Int) async !# User? {
return await withCheckedContinuation { cont in
getUser(id: id) { result in
cont.resume(returning: result)
}
}
}
let result = await getUser(id: 1)
Call site
async/await in Swift
await: only from within async context
func getUser(id: Int, _ completion: @escaping (User?) !# Void) {
let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!)
URLSession.shared.dataTask(with: req) { data, response, error in
guard let data = data else { return }
do {
let user = try JSONDecoder().decode(User.self, from: data)
completion(user)
} catch { completion(nil) }
}.resume()
}
await: only from within async context
struct AddArticleView: View {
@ObservedObject var viewModel: ArticlesViewModel
@State var newUrl: String = ""
func addUrl(url: String) {
Task.detached {
await viewModel.addNewArticle(from: url)
}
presentationMode.wrappedValue.dismiss()
}
var body: some View {
}
}
Previously: @asyncHandler
async/await in Swift
Run with confidence Engage users
Develop apps faster
Run with confidence
Crashlytics
Performance
Monitoring
Test Lab
App Distribution
Engage users
Analytics
Predictions
Cloud
Messaging
Remote
Config
A/B Testing
Dynamic
Links
In-app
Messaging
Develop apps faster
Auth
Cloud
Functions
Cloud
Firestore
Hosting
ML Kit
Realtime
Database
Cloud
Storage
bit.ly/what-is-firebase
Extensions
Machine
Learning
auth!$signInAnonymously()
let user = auth!$currentUser
print("User signed in with user ID: (user!$uid)")
This might be nil
auth!$signInAnonymously()
let user = auth!$currentUser
print("User signed in with user ID: (user!$uid)")
auth!$signInAnonymously { result, error in
guard let result = result else {
return
}
print("User signed in with user ID: (result.user.uid)")
}
Use callbacks instead
auth!$signInAnonymously()
let user = auth!$currentUser
print("User signed in with user ID: (user!$uid)")
auth!$signInAnonymously { result, error in
guard let result = result else {
return
}
print("User signed in with user ID: (result.user.uid)")
}
@Published var user: User?
!!%
auth!$signInAnonymously()
.map { $0.user }
.replaceError(with: nil)
.assign(to: &$user)
Combine
auth!$signInAnonymously { result, error in
guard let result = result else {
return
}
print("User signed in with user ID: (result.user.uid)")
}
Firebase and async/await
auth!$signInAnonymously { result, error in
guard let result = result else {
return
}
print("User signed in with user ID: (result.user.uid)")
}
Firebase and async/await
do {
let result = try await auth!$signInAnonymously()
print("User signed in with user ID: (result.user.uid)")
}
catch {
print(error)
}
Callback-style
Async/await
Here is how much work it was
to implement for Firebase:
.
(yep - it came almost for free)
async/await in Swift
async/await in Swift
Learn more
h!ps://pete"riese.dev/async-await-in-swi#
h!ps://www.youtube.com/watch?v=sEKw2BMcQtQ
Thanks!
Peter Friese
h!p://pete"riese.dev
@pete"riese
youtube.com/c/PeterFriese/
Follow me

More Related Content

PPTX
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
CODE BLUE
 
PDF
AWS Aurora 운영사례 (by 배은미)
I Goo Lee.
 
PPTX
ShEx vs SHACL
Jose Emilio Labra Gayo
 
PPTX
MySQL Indexing - Best practices for MySQL 5.6
MYXPLAIN
 
PDF
MySQL Multi-Source Replication for PL2016
Wagner Bianchi
 
PDF
Proxysql sharding
Marco Tusa
 
PPTX
Introdução a Grails: Um framework veloz e poderoso
Bruno Lopes
 
PPTX
Sql Injection attacks and prevention
helloanand
 
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
CODE BLUE
 
AWS Aurora 운영사례 (by 배은미)
I Goo Lee.
 
ShEx vs SHACL
Jose Emilio Labra Gayo
 
MySQL Indexing - Best practices for MySQL 5.6
MYXPLAIN
 
MySQL Multi-Source Replication for PL2016
Wagner Bianchi
 
Proxysql sharding
Marco Tusa
 
Introdução a Grails: Um framework veloz e poderoso
Bruno Lopes
 
Sql Injection attacks and prevention
helloanand
 

What's hot (20)

PPTX
Indexing with MongoDB
MongoDB
 
PPTX
Code injection
Gayatri Patel
 
PDF
JavaScript - Chapter 4 - Types and Statements
WebStackAcademy
 
PDF
마이크로 서비스를 위한 AWS Cloud Map & App Mesh - Saeho Kim (AWS Solutions Architect)
Amazon Web Services Korea
 
PPTX
Boas práticas técnica para um código limpo (Clean Code)
Rodrigo Kono
 
PDF
AWS Fargate와 Amazon ECS를 사용한 CI/CD 베스트 프랙티스 - 유재석, AWS 솔루션즈 아키텍트 :: AWS Build...
Amazon Web Services Korea
 
PDF
Intro ProxySQL
I Goo Lee
 
PPTX
Introdução a Framework Flask
Cleyson de Sousa Lima
 
PDF
Arquitetura Hexagonal: uma introdução
Morvana Bonin
 
PPTX
Maria db 이중화구성_고민하기
NeoClova
 
PPTX
Introdução a HTML5
Salvador Torres
 
PPT
Sql server performance tuning
ngupt28
 
PPTX
JSP: Introdução Parte 1
Elaine Cecília Gatto
 
PDF
Let's scale-out PostgreSQL using Citus (English)
Noriyoshi Shinoda
 
PPTX
Javascript best practices
Jayanga V. Liyanage
 
PDF
Amazon DocumentDB vs MongoDB 의 내부 아키텍쳐 와 장단점 비교
Amazon Web Services Korea
 
PDF
MariaDB MaxScale monitor 매뉴얼
NeoClova
 
PDF
Css to-scss
frontendne
 
PPTX
Prática de laboratório utilizando views, stored procedures e triggers
Daniel Maia
 
PDF
Transaction Management on Cassandra
Scalar, Inc.
 
Indexing with MongoDB
MongoDB
 
Code injection
Gayatri Patel
 
JavaScript - Chapter 4 - Types and Statements
WebStackAcademy
 
마이크로 서비스를 위한 AWS Cloud Map & App Mesh - Saeho Kim (AWS Solutions Architect)
Amazon Web Services Korea
 
Boas práticas técnica para um código limpo (Clean Code)
Rodrigo Kono
 
AWS Fargate와 Amazon ECS를 사용한 CI/CD 베스트 프랙티스 - 유재석, AWS 솔루션즈 아키텍트 :: AWS Build...
Amazon Web Services Korea
 
Intro ProxySQL
I Goo Lee
 
Introdução a Framework Flask
Cleyson de Sousa Lima
 
Arquitetura Hexagonal: uma introdução
Morvana Bonin
 
Maria db 이중화구성_고민하기
NeoClova
 
Introdução a HTML5
Salvador Torres
 
Sql server performance tuning
ngupt28
 
JSP: Introdução Parte 1
Elaine Cecília Gatto
 
Let's scale-out PostgreSQL using Citus (English)
Noriyoshi Shinoda
 
Javascript best practices
Jayanga V. Liyanage
 
Amazon DocumentDB vs MongoDB 의 내부 아키텍쳐 와 장단점 비교
Amazon Web Services Korea
 
MariaDB MaxScale monitor 매뉴얼
NeoClova
 
Css to-scss
frontendne
 
Prática de laboratório utilizando views, stored procedures e triggers
Daniel Maia
 
Transaction Management on Cassandra
Scalar, Inc.
 
Ad

Similar to async/await in Swift (20)

PDF
node.js practical guide to serverside javascript
Eldar Djafarov
 
PPTX
Android and REST
Roman Woźniak
 
PDF
Websockets talk at Rubyconf Uruguay 2010
Ismael Celis
 
PPTX
Bare-knuckle web development
Johannes Brodwall
 
PPTX
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
PDF
Data models in Angular 1 & 2
Adam Klein
 
KEY
CouchDB on Android
Sven Haiges
 
PPTX
Express JS
Alok Guha
 
PPTX
Ajax for dummies, and not only.
Nerd Tzanetopoulos
 
PDF
The Beauty Of Java Script V5a
rajivmordani
 
PPTX
Net/http and the http.handler interface
Joakim Gustin
 
PPTX
Net/http and the http.handler interface
Evolve
 
PDF
The Beauty of Java Script
Michael Girouard
 
PDF
Build web application by express
Shawn Meng
 
PDF
Reduxing like a pro
Boris Dinkevich
 
PDF
JavaScript Promise
Joseph Chiang
 
PDF
Phoenix + Reactで 社内システムを 密かに作ってる
Takahiro Kobaru
 
PDF
Rails is not just Ruby
Marco Otte-Witte
 
PDF
Server Side Swift: Vapor
Paweł Kowalczuk
 
KEY
Writing robust Node.js applications
Tom Croucher
 
node.js practical guide to serverside javascript
Eldar Djafarov
 
Android and REST
Roman Woźniak
 
Websockets talk at Rubyconf Uruguay 2010
Ismael Celis
 
Bare-knuckle web development
Johannes Brodwall
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
Data models in Angular 1 & 2
Adam Klein
 
CouchDB on Android
Sven Haiges
 
Express JS
Alok Guha
 
Ajax for dummies, and not only.
Nerd Tzanetopoulos
 
The Beauty Of Java Script V5a
rajivmordani
 
Net/http and the http.handler interface
Joakim Gustin
 
Net/http and the http.handler interface
Evolve
 
The Beauty of Java Script
Michael Girouard
 
Build web application by express
Shawn Meng
 
Reduxing like a pro
Boris Dinkevich
 
JavaScript Promise
Joseph Chiang
 
Phoenix + Reactで 社内システムを 密かに作ってる
Takahiro Kobaru
 
Rails is not just Ruby
Marco Otte-Witte
 
Server Side Swift: Vapor
Paweł Kowalczuk
 
Writing robust Node.js applications
Tom Croucher
 
Ad

More from Peter Friese (20)

PDF
Building Reusable SwiftUI Components
Peter Friese
 
PDF
Firebase & SwiftUI Workshop
Peter Friese
 
PDF
Building Reusable SwiftUI Components
Peter Friese
 
PDF
Firebase for Apple Developers - SwiftHeroes
Peter Friese
 
PDF
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
Peter Friese
 
PDF
Firebase for Apple Developers
Peter Friese
 
PDF
Building Apps with SwiftUI and Firebase
Peter Friese
 
PDF
Rapid Application Development with SwiftUI and Firebase
Peter Friese
 
PDF
Rapid Application Development with SwiftUI and Firebase
Peter Friese
 
PDF
6 Things You Didn't Know About Firebase Auth
Peter Friese
 
PDF
Five Things You Didn't Know About Firebase Auth
Peter Friese
 
PDF
Building High-Quality Apps for Google Assistant
Peter Friese
 
PDF
Building Conversational Experiences with Actions on Google
Peter Friese
 
PDF
Building Conversational Experiences with Actions on Google
Peter Friese
 
PDF
What's new in Android Wear 2.0
Peter Friese
 
PDF
Google Fit, Android Wear & Xamarin
Peter Friese
 
PDF
Introduction to Android Wear
Peter Friese
 
PDF
Google Play Services Rock
Peter Friese
 
PDF
Introduction to Android Wear
Peter Friese
 
PDF
Google+ for Mobile Apps on iOS and Android
Peter Friese
 
Building Reusable SwiftUI Components
Peter Friese
 
Firebase & SwiftUI Workshop
Peter Friese
 
Building Reusable SwiftUI Components
Peter Friese
 
Firebase for Apple Developers - SwiftHeroes
Peter Friese
 
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
Peter Friese
 
Firebase for Apple Developers
Peter Friese
 
Building Apps with SwiftUI and Firebase
Peter Friese
 
Rapid Application Development with SwiftUI and Firebase
Peter Friese
 
Rapid Application Development with SwiftUI and Firebase
Peter Friese
 
6 Things You Didn't Know About Firebase Auth
Peter Friese
 
Five Things You Didn't Know About Firebase Auth
Peter Friese
 
Building High-Quality Apps for Google Assistant
Peter Friese
 
Building Conversational Experiences with Actions on Google
Peter Friese
 
Building Conversational Experiences with Actions on Google
Peter Friese
 
What's new in Android Wear 2.0
Peter Friese
 
Google Fit, Android Wear & Xamarin
Peter Friese
 
Introduction to Android Wear
Peter Friese
 
Google Play Services Rock
Peter Friese
 
Introduction to Android Wear
Peter Friese
 
Google+ for Mobile Apps on iOS and Android
Peter Friese
 

Recently uploaded (20)

PDF
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
ESUG
 
PDF
QAware_Mario-Leander_Reimer_Architecting and Building a K8s-based AI Platform...
QAware GmbH
 
PDF
Build Multi-agent using Agent Development Kit
FadyIbrahim23
 
PDF
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 
PPTX
PFAS Reporting Requirements 2026 Are You Submission Ready Certivo.pptx
Certivo Inc
 
PPTX
TestNG for Java Testing and Automation testing
ssuser0213cb
 
PDF
Why Use Open Source Reporting Tools for Business Intelligence.pdf
Varsha Nayak
 
PPT
Why Reliable Server Maintenance Service in New York is Crucial for Your Business
Sam Vohra
 
PPTX
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
PPTX
Explanation about Structures in C language.pptx
Veeral Rathod
 
PDF
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
PDF
The Role of Automation and AI in EHS Management for Data Centers.pdf
TECH EHS Solution
 
PPTX
Presentation about variables and constant.pptx
safalsingh810
 
PDF
advancepresentationskillshdhdhhdhdhdhhfhf
jasmenrojas249
 
PPTX
Smart Panchayat Raj e-Governance App.pptx
Rohitnikam33
 
PPT
Activate_Methodology_Summary presentatio
annapureddyn
 
PDF
Teaching Reproducibility and Embracing Variability: From Floating-Point Exper...
University of Rennes, INSA Rennes, Inria/IRISA, CNRS
 
PDF
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
Hironori Washizaki
 
PDF
Appium Automation Testing Tutorial PDF: Learn Mobile Testing in 7 Days
jamescantor38
 
PPTX
AI-Ready Handoff: Auto-Summaries & Draft Emails from MQL to Slack in One Flow
bbedford2
 
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
ESUG
 
QAware_Mario-Leander_Reimer_Architecting and Building a K8s-based AI Platform...
QAware GmbH
 
Build Multi-agent using Agent Development Kit
FadyIbrahim23
 
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 
PFAS Reporting Requirements 2026 Are You Submission Ready Certivo.pptx
Certivo Inc
 
TestNG for Java Testing and Automation testing
ssuser0213cb
 
Why Use Open Source Reporting Tools for Business Intelligence.pdf
Varsha Nayak
 
Why Reliable Server Maintenance Service in New York is Crucial for Your Business
Sam Vohra
 
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
Explanation about Structures in C language.pptx
Veeral Rathod
 
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
The Role of Automation and AI in EHS Management for Data Centers.pdf
TECH EHS Solution
 
Presentation about variables and constant.pptx
safalsingh810
 
advancepresentationskillshdhdhhdhdhdhhfhf
jasmenrojas249
 
Smart Panchayat Raj e-Governance App.pptx
Rohitnikam33
 
Activate_Methodology_Summary presentatio
annapureddyn
 
Teaching Reproducibility and Embracing Variability: From Floating-Point Exper...
University of Rennes, INSA Rennes, Inria/IRISA, CNRS
 
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
Hironori Washizaki
 
Appium Automation Testing Tutorial PDF: Learn Mobile Testing in 7 Days
jamescantor38
 
AI-Ready Handoff: Auto-Summaries & Draft Emails from MQL to Slack in One Flow
bbedford2
 

async/await in Swift

  • 1. async/await in Swi! Photo by Stephen H on Unsplash Peter Friese | Firebase Developer Advocate | @pete!riese
  • 2. let req = URLRequest(url: URL(string: “https:!"yourapi/path“)!) let task = URLSession.shared.dataTask(with: req) { data, response, error in !" do stuff once data arrives } task.resume() Asynchronous code is everywhere completion handler
  • 3. func process(url: String, completion: @escaping (Article) !# Void) { self.fetchArticle(from: url) { html in self.extractTitle(from: html) { title in self.extractText(from: html) { text in self.extractImage(from: url) { imageUrl in self.inferTags(from: text) { tags in let article = Article(url: url, title: title, tags: tags, imageUrlString: imageUrl) completion(article) } } } } } } A more complex example
  • 4. extension ArticleAnalyser { func process(url: String, completion: @escaping (Article) !# Void) { self.fetchArticle(from: url) { result in switch result { case .failure(let error): print(error.localizedDescription) case .success(let html): self.extractTitle(from: html) { result in switch result { case .failure(let error): print(error.localizedDescription) case .success(let title): self.extractText(from: html) { result in switch result { case .failure(let error): print(error.localizedDescription) case .success(let text): Let’s add some error handling… !
  • 5. extension AsyncArticleAnalyser { func process(url: String) async throws !# Article { let htmlText = try await fetchArticle(from: url) let text = try await extractText(from: htmlText) let title = try await extractTitle(from: htmlText) let imageUrl = try await extractImage(from: url) let tags = await inferTags(from: text) return Article(url: url, title: title, tags: tags, imageUrlString: imageUrl) } } How about this? Swift 5.5
  • 6. This is just the toolchain, really
  • 8. func helloWorld(name: String, completion: (String) !# Void) { completion("Hello, (name)") } Let’s convert a callback-based function! func greeting() { helloWorld(name: "Peter") { result in print(result) } }
  • 9. func helloWorld(name: String, completion: (String) !# Void) { completion("Hello, (name)") } Let’s convert a callback-based function! func helloWorld(name: String) async !# String { return "Hello, (name)" } Before After
  • 10. func helloWorld(name: String, completion: (String) !# Void) { completion("Hello, (name)") } Let’s convert a callback-based function! let result = await helloWorld(name: "Peter") func helloWorld(name: String) async !# String { return "Hello, (name)" } Before After Call site
  • 11. Sometimes, it’s more complicated, though func getUser(id: Int, _ completion: @escaping (User?) !# Void) { let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!) URLSession.shared.dataTask(with: req) { data, response, error in guard let data = data else { return } do { let user = try JSONDecoder().decode(User.self, from: data) completion(user) } catch { completion(nil) } }.resume() } func greeting() { getUser(id: 1) { result in if let userName = result!$name { print("Hello, (userName)") } } }
  • 12. Sometimes, it’s more complicated, though func getUser(id: Int, _ completion: @escaping (User?) !# Void) { let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!) URLSession.shared.dataTask(with: req) { data, response, error in guard let data = data else { return } do { let user = try JSONDecoder().decode(User.self, from: data) completion(user) } catch { completion(nil) } }.resume() } Let’s keep this entire function func getUser(id: Int, _ completion: @escaping (User?) !# Void) { !!% }
  • 13. func getUser(id: Int, _ completion: @escaping (User?) !# Void) { let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!) URLSession.shared.dataTask(with: req) { data, response, error in guard let data = data else { return } do { let user = try JSONDecoder().decode(User.self, from: data) completion(user) } catch { completion(nil) } }.resume() } Sometimes, it’s more complicated, though func getUser(id: Int, _ completion: @escaping (User?) !# Void) { !!% } func getUser(id: Int) async !# User? { return await withCheckedContinuation { cont in getUser(id: id) { result in cont.resume(returning: result) } } } Introduce this wrapper
  • 14. func getUser(id: Int, _ completion: @escaping (User?) !# Void) { let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!) URLSession.shared.dataTask(with: req) { data, response, error in guard let data = data else { return } do { let user = try JSONDecoder().decode(User.self, from: data) completion(user) } catch { completion(nil) } }.resume() } Sometimes, it’s more complicated, though func getUser(id: Int, _ completion: @escaping (User?) !# Void) { !!% } func getUser(id: Int) async !# User? { return await withCheckedContinuation { cont in getUser(id: id) { result in cont.resume(returning: result) } } } Call the original here
  • 15. func getUser(id: Int, _ completion: @escaping (User?) !# Void) { let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!) URLSession.shared.dataTask(with: req) { data, response, error in guard let data = data else { return } do { let user = try JSONDecoder().decode(User.self, from: data) completion(user) } catch { completion(nil) } }.resume() } Sometimes, it’s more complicated, though func getUser(id: Int, _ completion: @escaping (User?) !# Void) { !!% } func getUser(id: Int) async !# User? { return await withCheckedContinuation { cont in getUser(id: id) { result in cont.resume(returning: result) } } } Create a continuation Resume once we receive a result
  • 16. func getUser(id: Int, _ completion: @escaping (User?) !# Void) { let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!) URLSession.shared.dataTask(with: req) { data, response, error in guard let data = data else { return } do { let user = try JSONDecoder().decode(User.self, from: data) completion(user) } catch { completion(nil) } }.resume() } Sometimes, it’s more complicated, though func getUser(id: Int, _ completion: @escaping (User?) !# Void) { !!% } func getUser(id: Int) async !# User? { return await withCheckedContinuation { cont in getUser(id: id) { result in cont.resume(returning: result) } } } let result = await getUser(id: 1) Call site
  • 18. await: only from within async context
  • 19. func getUser(id: Int, _ completion: @escaping (User?) !# Void) { let req = URLRequest(url: URL(string: "https:!"jsonplaceholder./users/(id)")!) URLSession.shared.dataTask(with: req) { data, response, error in guard let data = data else { return } do { let user = try JSONDecoder().decode(User.self, from: data) completion(user) } catch { completion(nil) } }.resume() } await: only from within async context struct AddArticleView: View { @ObservedObject var viewModel: ArticlesViewModel @State var newUrl: String = "" func addUrl(url: String) { Task.detached { await viewModel.addNewArticle(from: url) } presentationMode.wrappedValue.dismiss() } var body: some View { } } Previously: @asyncHandler
  • 21. Run with confidence Engage users Develop apps faster
  • 22. Run with confidence Crashlytics Performance Monitoring Test Lab App Distribution Engage users Analytics Predictions Cloud Messaging Remote Config A/B Testing Dynamic Links In-app Messaging Develop apps faster Auth Cloud Functions Cloud Firestore Hosting ML Kit Realtime Database Cloud Storage bit.ly/what-is-firebase Extensions Machine Learning
  • 23. auth!$signInAnonymously() let user = auth!$currentUser print("User signed in with user ID: (user!$uid)") This might be nil
  • 24. auth!$signInAnonymously() let user = auth!$currentUser print("User signed in with user ID: (user!$uid)") auth!$signInAnonymously { result, error in guard let result = result else { return } print("User signed in with user ID: (result.user.uid)") } Use callbacks instead
  • 25. auth!$signInAnonymously() let user = auth!$currentUser print("User signed in with user ID: (user!$uid)") auth!$signInAnonymously { result, error in guard let result = result else { return } print("User signed in with user ID: (result.user.uid)") } @Published var user: User? !!% auth!$signInAnonymously() .map { $0.user } .replaceError(with: nil) .assign(to: &$user) Combine
  • 26. auth!$signInAnonymously { result, error in guard let result = result else { return } print("User signed in with user ID: (result.user.uid)") } Firebase and async/await
  • 27. auth!$signInAnonymously { result, error in guard let result = result else { return } print("User signed in with user ID: (result.user.uid)") } Firebase and async/await do { let result = try await auth!$signInAnonymously() print("User signed in with user ID: (result.user.uid)") } catch { print(error) } Callback-style Async/await
  • 28. Here is how much work it was to implement for Firebase: . (yep - it came almost for free)