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

What's hot

Defending against Java Deserialization Vulnerabilities
 Defending against Java Deserialization Vulnerabilities Defending against Java Deserialization Vulnerabilities
Defending against Java Deserialization Vulnerabilities
Luca Carettoni
 
CORS and (in)security
CORS and (in)securityCORS and (in)security
CORS and (in)security
n|u - The Open Security Community
 
Blind XSS & Click Jacking
Blind XSS & Click JackingBlind XSS & Click Jacking
Blind XSS & Click Jacking
n|u - The Open Security Community
 
Applications secure by default
Applications secure by defaultApplications secure by default
Applications secure by default
SecuRing
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js Express
Eyal Vardi
 
OWASP AppSecCali 2015 - Marshalling Pickles
OWASP AppSecCali 2015 - Marshalling PicklesOWASP AppSecCali 2015 - Marshalling Pickles
OWASP AppSecCali 2015 - Marshalling Pickles
Christopher Frohoff
 
Neat tricks to bypass CSRF-protection
Neat tricks to bypass CSRF-protectionNeat tricks to bypass CSRF-protection
Neat tricks to bypass CSRF-protection
Mikhail Egorov
 
Saml authentication bypass
Saml authentication bypassSaml authentication bypass
Saml authentication bypass
Tarachand Verma
 
BDD with CucumberJS and WebdriverIO
BDD with CucumberJS and WebdriverIOBDD with CucumberJS and WebdriverIO
BDD with CucumberJS and WebdriverIO
M Rizwanur Rashid
 
A Forgotten HTTP Invisibility Cloak
A Forgotten HTTP Invisibility CloakA Forgotten HTTP Invisibility Cloak
A Forgotten HTTP Invisibility Cloak
Soroush Dalili
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
Joshua Long
 
How to Prevent RFI and LFI Attacks
How to Prevent RFI and LFI AttacksHow to Prevent RFI and LFI Attacks
How to Prevent RFI and LFI Attacks
Imperva
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
IvΓ‘n FernΓ‘ndez Perea
 
Ssrf
SsrfSsrf
Design Beautiful REST + JSON APIs
Design Beautiful REST + JSON APIsDesign Beautiful REST + JSON APIs
Design Beautiful REST + JSON APIs
Stormpath
 
XXE: How to become a Jedi
XXE: How to become a JediXXE: How to become a Jedi
XXE: How to become a Jedi
Yaroslav Babin
 
Cross site scripting
Cross site scriptingCross site scripting
Cross site scripting
n|u - The Open Security Community
 
HTTP Request and Response Structure
HTTP Request and Response StructureHTTP Request and Response Structure
HTTP Request and Response Structure
BhagyashreeGajera1
 
HTTP Request Smuggling via higher HTTP versions
HTTP Request Smuggling via higher HTTP versionsHTTP Request Smuggling via higher HTTP versions
HTTP Request Smuggling via higher HTTP versions
neexemil
 
Postman Collection Format v2.0 (pre-draft)
Postman Collection Format v2.0 (pre-draft)Postman Collection Format v2.0 (pre-draft)
Postman Collection Format v2.0 (pre-draft)
Postman
 

What's hot (20)

Defending against Java Deserialization Vulnerabilities
 Defending against Java Deserialization Vulnerabilities Defending against Java Deserialization Vulnerabilities
Defending against Java Deserialization Vulnerabilities
 
CORS and (in)security
CORS and (in)securityCORS and (in)security
CORS and (in)security
 
Blind XSS & Click Jacking
Blind XSS & Click JackingBlind XSS & Click Jacking
Blind XSS & Click Jacking
 
Applications secure by default
Applications secure by defaultApplications secure by default
Applications secure by default
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js Express
 
OWASP AppSecCali 2015 - Marshalling Pickles
OWASP AppSecCali 2015 - Marshalling PicklesOWASP AppSecCali 2015 - Marshalling Pickles
OWASP AppSecCali 2015 - Marshalling Pickles
 
Neat tricks to bypass CSRF-protection
Neat tricks to bypass CSRF-protectionNeat tricks to bypass CSRF-protection
Neat tricks to bypass CSRF-protection
 
Saml authentication bypass
Saml authentication bypassSaml authentication bypass
Saml authentication bypass
 
BDD with CucumberJS and WebdriverIO
BDD with CucumberJS and WebdriverIOBDD with CucumberJS and WebdriverIO
BDD with CucumberJS and WebdriverIO
 
A Forgotten HTTP Invisibility Cloak
A Forgotten HTTP Invisibility CloakA Forgotten HTTP Invisibility Cloak
A Forgotten HTTP Invisibility Cloak
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
How to Prevent RFI and LFI Attacks
How to Prevent RFI and LFI AttacksHow to Prevent RFI and LFI Attacks
How to Prevent RFI and LFI Attacks
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
Ssrf
SsrfSsrf
Ssrf
 
Design Beautiful REST + JSON APIs
Design Beautiful REST + JSON APIsDesign Beautiful REST + JSON APIs
Design Beautiful REST + JSON APIs
 
XXE: How to become a Jedi
XXE: How to become a JediXXE: How to become a Jedi
XXE: How to become a Jedi
 
Cross site scripting
Cross site scriptingCross site scripting
Cross site scripting
 
HTTP Request and Response Structure
HTTP Request and Response StructureHTTP Request and Response Structure
HTTP Request and Response Structure
 
HTTP Request Smuggling via higher HTTP versions
HTTP Request Smuggling via higher HTTP versionsHTTP Request Smuggling via higher HTTP versions
HTTP Request Smuggling via higher HTTP versions
 
Postman Collection Format v2.0 (pre-draft)
Postman Collection Format v2.0 (pre-draft)Postman Collection Format v2.0 (pre-draft)
Postman Collection Format v2.0 (pre-draft)
 

Similar to async/await in Swift

node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascript
Eldar Djafarov
 
Android and REST
Android and RESTAndroid and REST
Android and REST
Roman WoΕΊniak
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010
Ismael Celis
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web development
Johannes Brodwall
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
Data models in Angular 1 & 2
Data models in Angular 1 & 2Data models in Angular 1 & 2
Data models in Angular 1 & 2
Adam Klein
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
Sven Haiges
 
Express JS
Express JSExpress JS
Express JS
Alok Guha
 
Ajax for dummies, and not only.
Ajax for dummies, and not only.Ajax for dummies, and not only.
Ajax for dummies, and not only.
Nerd Tzanetopoulos
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
rajivmordani
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
Joakim Gustin
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
Evolve
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
Michael Girouard
 
Build web application by express
Build web application by expressBuild web application by express
Build web application by express
Shawn Meng
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
Boris Dinkevich
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
Joseph Chiang
 
Phoenix + Reactで 瀾内システムを ε―†γ‹γ«δ½œγ£γ¦γ‚‹
Phoenix + Reactで 瀾内システムを ε―†γ‹γ«δ½œγ£γ¦γ‚‹Phoenix + Reactで 瀾内システムを ε―†γ‹γ«δ½œγ£γ¦γ‚‹
Phoenix + Reactで 瀾内システムを ε―†γ‹γ«δ½œγ£γ¦γ‚‹
Takahiro Kobaru
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
Marco Otte-Witte
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
PaweΕ‚ Kowalczuk
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
Tom Croucher
 

Similar to async/await in Swift (20)

node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascript
 
Android and REST
Android and RESTAndroid and REST
Android and REST
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web development
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Data models in Angular 1 & 2
Data models in Angular 1 & 2Data models in Angular 1 & 2
Data models in Angular 1 & 2
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Express JS
Express JSExpress JS
Express JS
 
Ajax for dummies, and not only.
Ajax for dummies, and not only.Ajax for dummies, and not only.
Ajax for dummies, and not only.
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
 
Build web application by express
Build web application by expressBuild web application by express
Build web application by express
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
 
Phoenix + Reactで 瀾内システムを ε―†γ‹γ«δ½œγ£γ¦γ‚‹
Phoenix + Reactで 瀾内システムを ε―†γ‹γ«δ½œγ£γ¦γ‚‹Phoenix + Reactで 瀾内システムを ε―†γ‹γ«δ½œγ£γ¦γ‚‹
Phoenix + Reactで 瀾内システムを ε―†γ‹γ«δ½œγ£γ¦γ‚‹
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 

More from Peter Friese

Building Reusable SwiftUI Components
Building Reusable SwiftUI ComponentsBuilding Reusable SwiftUI Components
Building Reusable SwiftUI Components
Peter Friese
 
Firebase & SwiftUI Workshop
Firebase & SwiftUI WorkshopFirebase & SwiftUI Workshop
Firebase & SwiftUI Workshop
Peter Friese
 
Building Reusable SwiftUI Components
Building Reusable SwiftUI ComponentsBuilding Reusable SwiftUI Components
Building Reusable SwiftUI Components
Peter Friese
 
Firebase for Apple Developers - SwiftHeroes
Firebase for Apple Developers - SwiftHeroesFirebase for Apple Developers - SwiftHeroes
Firebase for Apple Developers - SwiftHeroes
Peter Friese
 
 + ο”₯ = ❀️ (Firebase for Apple Developers) at Swift Leeds
 + ο”₯ = ❀️ (Firebase for Apple Developers) at Swift Leeds + ο”₯ = ❀️ (Firebase for Apple Developers) at Swift Leeds
 + ο”₯ = ❀️ (Firebase for Apple Developers) at Swift Leeds
Peter Friese
 
Firebase for Apple Developers
Firebase for Apple DevelopersFirebase for Apple Developers
Firebase for Apple Developers
Peter Friese
 
Building Apps with SwiftUI and Firebase
Building Apps with SwiftUI and FirebaseBuilding Apps with SwiftUI and Firebase
Building Apps with SwiftUI and Firebase
Peter Friese
 
Rapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and FirebaseRapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and Firebase
Peter Friese
 
Rapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and FirebaseRapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and Firebase
Peter Friese
 
6 Things You Didn't Know About Firebase Auth
6 Things You Didn't Know About Firebase Auth6 Things You Didn't Know About Firebase Auth
6 Things You Didn't Know About Firebase Auth
Peter Friese
 
Five Things You Didn't Know About Firebase Auth
Five Things You Didn't Know About Firebase AuthFive Things You Didn't Know About Firebase Auth
Five Things You Didn't Know About Firebase Auth
Peter Friese
 
Building High-Quality Apps for Google Assistant
Building High-Quality Apps for Google AssistantBuilding High-Quality Apps for Google Assistant
Building High-Quality Apps for Google Assistant
Peter Friese
 
Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google
Peter Friese
 
Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on GoogleBuilding Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google
Peter Friese
 
What's new in Android Wear 2.0
What's new in Android Wear 2.0What's new in Android Wear 2.0
What's new in Android Wear 2.0
Peter Friese
 
Google Fit, Android Wear & Xamarin
Google Fit, Android Wear & XamarinGoogle Fit, Android Wear & Xamarin
Google Fit, Android Wear & Xamarin
Peter Friese
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android Wear
Peter Friese
 
Google Play Services Rock
Google Play Services RockGoogle Play Services Rock
Google Play Services Rock
Peter Friese
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android Wear
Peter Friese
 
Google+ for Mobile Apps on iOS and Android
Google+ for Mobile Apps on iOS and AndroidGoogle+ for Mobile Apps on iOS and Android
Google+ for Mobile Apps on iOS and Android
Peter Friese
 

More from Peter Friese (20)

Building Reusable SwiftUI Components
Building Reusable SwiftUI ComponentsBuilding Reusable SwiftUI Components
Building Reusable SwiftUI Components
 
Firebase & SwiftUI Workshop
Firebase & SwiftUI WorkshopFirebase & SwiftUI Workshop
Firebase & SwiftUI Workshop
 
Building Reusable SwiftUI Components
Building Reusable SwiftUI ComponentsBuilding Reusable SwiftUI Components
Building Reusable SwiftUI Components
 
Firebase for Apple Developers - SwiftHeroes
Firebase for Apple Developers - SwiftHeroesFirebase for Apple Developers - SwiftHeroes
Firebase for Apple Developers - SwiftHeroes
 
 + ο”₯ = ❀️ (Firebase for Apple Developers) at Swift Leeds
 + ο”₯ = ❀️ (Firebase for Apple Developers) at Swift Leeds + ο”₯ = ❀️ (Firebase for Apple Developers) at Swift Leeds
 + ο”₯ = ❀️ (Firebase for Apple Developers) at Swift Leeds
 
Firebase for Apple Developers
Firebase for Apple DevelopersFirebase for Apple Developers
Firebase for Apple Developers
 
Building Apps with SwiftUI and Firebase
Building Apps with SwiftUI and FirebaseBuilding Apps with SwiftUI and Firebase
Building Apps with SwiftUI and Firebase
 
Rapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and FirebaseRapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and Firebase
 
Rapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and FirebaseRapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and Firebase
 
6 Things You Didn't Know About Firebase Auth
6 Things You Didn't Know About Firebase Auth6 Things You Didn't Know About Firebase Auth
6 Things You Didn't Know About Firebase Auth
 
Five Things You Didn't Know About Firebase Auth
Five Things You Didn't Know About Firebase AuthFive Things You Didn't Know About Firebase Auth
Five Things You Didn't Know About Firebase Auth
 
Building High-Quality Apps for Google Assistant
Building High-Quality Apps for Google AssistantBuilding High-Quality Apps for Google Assistant
Building High-Quality Apps for Google Assistant
 
Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google
 
Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on GoogleBuilding Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google
 
What's new in Android Wear 2.0
What's new in Android Wear 2.0What's new in Android Wear 2.0
What's new in Android Wear 2.0
 
Google Fit, Android Wear & Xamarin
Google Fit, Android Wear & XamarinGoogle Fit, Android Wear & Xamarin
Google Fit, Android Wear & Xamarin
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android Wear
 
Google Play Services Rock
Google Play Services RockGoogle Play Services Rock
Google Play Services Rock
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android Wear
 
Google+ for Mobile Apps on iOS and Android
Google+ for Mobile Apps on iOS and AndroidGoogle+ for Mobile Apps on iOS and Android
Google+ for Mobile Apps on iOS and Android
 

Recently uploaded

Folding Cheat Sheet #7 - seventh in a series
Folding Cheat Sheet #7 - seventh in a seriesFolding Cheat Sheet #7 - seventh in a series
Folding Cheat Sheet #7 - seventh in a series
Philip Schwarz
 
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data PlatformAlluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio, Inc.
 
dachnug51 - HCL Domino Roadmap .pdf
dachnug51 - HCL Domino Roadmap      .pdfdachnug51 - HCL Domino Roadmap      .pdf
dachnug51 - HCL Domino Roadmap .pdf
DNUG e.V.
 
mobile-app-development-company-in-noida.pdf
mobile-app-development-company-in-noida.pdfmobile-app-development-company-in-noida.pdf
mobile-app-development-company-in-noida.pdf
Mobile App Development Company in Noida - Drona Infotech
 
ENISA Threat Landscape 2023 documentation
ENISA Threat Landscape 2023 documentationENISA Threat Landscape 2023 documentation
ENISA Threat Landscape 2023 documentation
sofiafernandezon
 
β‚ΉCall β‚ΉGirls Andheri West 09967584737 Deshi Chori Near You
β‚ΉCall β‚ΉGirls Andheri West 09967584737 Deshi Chori Near Youβ‚ΉCall β‚ΉGirls Andheri West 09967584737 Deshi Chori Near You
β‚ΉCall β‚ΉGirls Andheri West 09967584737 Deshi Chori Near You
shristi verma
 
ANSYS Mechanical APDL Introductory Tutorials.pdf
ANSYS Mechanical APDL Introductory Tutorials.pdfANSYS Mechanical APDL Introductory Tutorials.pdf
ANSYS Mechanical APDL Introductory Tutorials.pdf
sachin chaurasia
 
Mumbai @Call @Girls Whatsapp 9930687706 With High Profile Service
Mumbai @Call @Girls Whatsapp 9930687706 With High Profile ServiceMumbai @Call @Girls Whatsapp 9930687706 With High Profile Service
Mumbai @Call @Girls Whatsapp 9930687706 With High Profile Service
kolkata dolls
 
Ported to Cloud with Wing_ Blue ZnZone app from _Hexagonal Architecture Expla...
Ported to Cloud with Wing_ Blue ZnZone app from _Hexagonal Architecture Expla...Ported to Cloud with Wing_ Blue ZnZone app from _Hexagonal Architecture Expla...
Ported to Cloud with Wing_ Blue ZnZone app from _Hexagonal Architecture Expla...
Asher Sterkin
 
@β„‚all @Girls Kolkata ꧁❀ 000000000 ❀꧂@β„‚all @Girls Service Vip Top Model Safe
@β„‚all @Girls Kolkata  ꧁❀ 000000000 ❀꧂@β„‚all @Girls Service Vip Top Model Safe@β„‚all @Girls Kolkata  ꧁❀ 000000000 ❀꧂@β„‚all @Girls Service Vip Top Model Safe
@β„‚all @Girls Kolkata ꧁❀ 000000000 ❀꧂@β„‚all @Girls Service Vip Top Model Safe
Misti Soneji
 
Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)
miso_uam
 
@Call @Girls in Aligarh πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Class A...
 @Call @Girls in Aligarh πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Class A... @Call @Girls in Aligarh πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Class A...
@Call @Girls in Aligarh πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Class A...
msriya3
 
Top 10 Tips To Get Google AdSense For Your Website
Top 10 Tips To Get Google AdSense For Your WebsiteTop 10 Tips To Get Google AdSense For Your Website
Top 10 Tips To Get Google AdSense For Your Website
e-Definers Technology
 
@Call @Girls in Saharanpur πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Clas...
 @Call @Girls in Saharanpur πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Clas... @Call @Girls in Saharanpur πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Clas...
@Call @Girls in Saharanpur πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Clas...
AlinaDevecerski
 
dachnug51 - HCLs evolution of the employee experience platform.pdf
dachnug51 - HCLs evolution of the employee experience platform.pdfdachnug51 - HCLs evolution of the employee experience platform.pdf
dachnug51 - HCLs evolution of the employee experience platform.pdf
DNUG e.V.
 
Addressing the Top 9 User Pain Points with Visual Design Elements.pptx
Addressing the Top 9 User Pain Points with Visual Design Elements.pptxAddressing the Top 9 User Pain Points with Visual Design Elements.pptx
Addressing the Top 9 User Pain Points with Visual Design Elements.pptx
Sparity1
 
@Call @Girls in Ahmedabad πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Ahmedabad Ava...
 @Call @Girls in Ahmedabad πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Ahmedabad Ava... @Call @Girls in Ahmedabad πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Ahmedabad Ava...
@Call @Girls in Ahmedabad πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Ahmedabad Ava...
DiyaSharma6551
 
Kolkata @Call @Girls πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Genuine WhatsApp Number for Real Meet
Kolkata @Call @Girls πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Genuine WhatsApp Number for Real MeetKolkata @Call @Girls πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Genuine WhatsApp Number for Real Meet
Kolkata @Call @Girls πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Genuine WhatsApp Number for Real Meet
lovelykumarilk789
 
@Call @Girls in Surat πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Surat Avaulable
 @Call @Girls in Surat πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Surat Avaulable @Call @Girls in Surat πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Surat Avaulable
@Call @Girls in Surat πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Surat Avaulable
DiyaSharma6551
 
@Call @Girls in Kolkata πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Kolkata Avaulable
 @Call @Girls in Kolkata πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Kolkata Avaulable @Call @Girls in Kolkata πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Kolkata Avaulable
@Call @Girls in Kolkata πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Kolkata Avaulable
DiyaSharma6551
 

Recently uploaded (20)

Folding Cheat Sheet #7 - seventh in a series
Folding Cheat Sheet #7 - seventh in a seriesFolding Cheat Sheet #7 - seventh in a series
Folding Cheat Sheet #7 - seventh in a series
 
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data PlatformAlluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
 
dachnug51 - HCL Domino Roadmap .pdf
dachnug51 - HCL Domino Roadmap      .pdfdachnug51 - HCL Domino Roadmap      .pdf
dachnug51 - HCL Domino Roadmap .pdf
 
mobile-app-development-company-in-noida.pdf
mobile-app-development-company-in-noida.pdfmobile-app-development-company-in-noida.pdf
mobile-app-development-company-in-noida.pdf
 
ENISA Threat Landscape 2023 documentation
ENISA Threat Landscape 2023 documentationENISA Threat Landscape 2023 documentation
ENISA Threat Landscape 2023 documentation
 
β‚ΉCall β‚ΉGirls Andheri West 09967584737 Deshi Chori Near You
β‚ΉCall β‚ΉGirls Andheri West 09967584737 Deshi Chori Near Youβ‚ΉCall β‚ΉGirls Andheri West 09967584737 Deshi Chori Near You
β‚ΉCall β‚ΉGirls Andheri West 09967584737 Deshi Chori Near You
 
ANSYS Mechanical APDL Introductory Tutorials.pdf
ANSYS Mechanical APDL Introductory Tutorials.pdfANSYS Mechanical APDL Introductory Tutorials.pdf
ANSYS Mechanical APDL Introductory Tutorials.pdf
 
Mumbai @Call @Girls Whatsapp 9930687706 With High Profile Service
Mumbai @Call @Girls Whatsapp 9930687706 With High Profile ServiceMumbai @Call @Girls Whatsapp 9930687706 With High Profile Service
Mumbai @Call @Girls Whatsapp 9930687706 With High Profile Service
 
Ported to Cloud with Wing_ Blue ZnZone app from _Hexagonal Architecture Expla...
Ported to Cloud with Wing_ Blue ZnZone app from _Hexagonal Architecture Expla...Ported to Cloud with Wing_ Blue ZnZone app from _Hexagonal Architecture Expla...
Ported to Cloud with Wing_ Blue ZnZone app from _Hexagonal Architecture Expla...
 
@β„‚all @Girls Kolkata ꧁❀ 000000000 ❀꧂@β„‚all @Girls Service Vip Top Model Safe
@β„‚all @Girls Kolkata  ꧁❀ 000000000 ❀꧂@β„‚all @Girls Service Vip Top Model Safe@β„‚all @Girls Kolkata  ꧁❀ 000000000 ❀꧂@β„‚all @Girls Service Vip Top Model Safe
@β„‚all @Girls Kolkata ꧁❀ 000000000 ❀꧂@β„‚all @Girls Service Vip Top Model Safe
 
Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)
 
@Call @Girls in Aligarh πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Class A...
 @Call @Girls in Aligarh πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Class A... @Call @Girls in Aligarh πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Class A...
@Call @Girls in Aligarh πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Class A...
 
Top 10 Tips To Get Google AdSense For Your Website
Top 10 Tips To Get Google AdSense For Your WebsiteTop 10 Tips To Get Google AdSense For Your Website
Top 10 Tips To Get Google AdSense For Your Website
 
@Call @Girls in Saharanpur πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Clas...
 @Call @Girls in Saharanpur πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Clas... @Call @Girls in Saharanpur πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Clas...
@Call @Girls in Saharanpur πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Tanisha Sharma Best High Clas...
 
dachnug51 - HCLs evolution of the employee experience platform.pdf
dachnug51 - HCLs evolution of the employee experience platform.pdfdachnug51 - HCLs evolution of the employee experience platform.pdf
dachnug51 - HCLs evolution of the employee experience platform.pdf
 
Addressing the Top 9 User Pain Points with Visual Design Elements.pptx
Addressing the Top 9 User Pain Points with Visual Design Elements.pptxAddressing the Top 9 User Pain Points with Visual Design Elements.pptx
Addressing the Top 9 User Pain Points with Visual Design Elements.pptx
 
@Call @Girls in Ahmedabad πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Ahmedabad Ava...
 @Call @Girls in Ahmedabad πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Ahmedabad Ava... @Call @Girls in Ahmedabad πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Ahmedabad Ava...
@Call @Girls in Ahmedabad πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Ahmedabad Ava...
 
Kolkata @Call @Girls πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Genuine WhatsApp Number for Real Meet
Kolkata @Call @Girls πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Genuine WhatsApp Number for Real MeetKolkata @Call @Girls πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰ Genuine WhatsApp Number for Real Meet
Kolkata @Call @Girls πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Genuine WhatsApp Number for Real Meet
 
@Call @Girls in Surat πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Surat Avaulable
 @Call @Girls in Surat πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Surat Avaulable @Call @Girls in Surat πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Surat Avaulable
@Call @Girls in Surat πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Surat Avaulable
 
@Call @Girls in Kolkata πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Kolkata Avaulable
 @Call @Girls in Kolkata πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Kolkata Avaulable @Call @Girls in Kolkata πŸ±β€πŸ‰  XXXXXXXXXX πŸ±β€πŸ‰  Best High Class Kolkata Avaulable
@Call @Girls in Kolkata πŸ±β€πŸ‰ XXXXXXXXXX πŸ±β€πŸ‰ Best High Class Kolkata Avaulable
 

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)