This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// the compiler is happy now | |
func escapingSendableClosure(_ then: @escaping @Sendable () -> Void) { | |
Task { | |
then() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Error: Capture of 'then' with non-sendable type | |
// '() -> Void' in a `@Sendable` closure | |
func escapingClosure(_ then: @escaping () -> Void) { | |
Task { | |
then() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// safe to pass between arbitrary Tasks, async functions, and Actors | |
struct UserData: Sendable { | |
var id: Int | |
var name: String | |
} | |
// safe because properties are immutable and we can't subclass | |
final class User: Sendable { | |
let name: String | |
let age: Int |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import AuthenticationServices | |
func signInWithGoogle() async throws -> String { | |
try await withCheckedThrowingContinuation { continuation in | |
let session = ASWebAuthenticationSession( | |
url: URL(string: "https://oauth.example.com/auth")!, | |
callbackURLScheme: "myapp" | |
) { callbackURL, error in | |
if let error = error { | |
continuation.resume(throwing: error) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public protocol View { | |
associatedtype Body : View | |
@ViewBuilder @MainActor var body: Self.Body { get } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// All code runs on MainActor | |
@MainActor | |
func updateUI(with text: String) { | |
label.text = text | |
} | |
// properties and functions implicitly marked @MainActor | |
@MainActor | |
class ViewModel: ObservableObject { | |
// ... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
actor BankAccount { | |
// ... | |
} | |
let account = BankAccount() | |
await account.deposit(1000) | |
// simultaneously attempt to withdraw | |
async let one = account.withdraw(500) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class BankAccount { | |
enum BankAccountError: Error { | |
case insufficientFunds | |
} | |
private(set) var balance: Double = 0 | |
func deposit(_ amount: Double) { | |
balance += amount | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// user IDs not known at compile-time | |
let userIds = getUserIds() // [1, 2, 3, 4, 5] | |
let users = await withTaskGroup(of: User.self) { group in | |
for id in userIds { | |
group.addTask { | |
await fetchUser(id: id) | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async let user = fetchUser(id: 1) | |
async let posts = fetchPosts(userId: 1) | |
async let friends = fetchFriends(userId: 1) | |
// no suspension yet | |
// execution kicks off all child tasks immediately | |
// suspension only happens at the first await | |
self.user = await user // fetchUser() async | |
self.posts = try? await posts // fetchPosts() async throws | |
self.friends = try await friends // fetchFriends() async throws |