Skip to content

Instantly share code, notes, and snippets.

View jacobsapps's full-sized avatar

Jacob Bartlett jacobsapps

View GitHub Profile
// the compiler is happy now
func escapingSendableClosure(_ then: @escaping @Sendable () -> Void) {
Task {
then()
}
}
// Error: Capture of 'then' with non-sendable type
// '() -> Void' in a `@Sendable` closure
func escapingClosure(_ then: @escaping () -> Void) {
Task {
then()
}
}
// 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
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)
public protocol View {
associatedtype Body : View
@ViewBuilder @MainActor var body: Self.Body { get }
}
// All code runs on MainActor
@MainActor
func updateUI(with text: String) {
label.text = text
}
// properties and functions implicitly marked @MainActor
@MainActor
class ViewModel: ObservableObject {
// ...
actor BankAccount {
// ...
}
let account = BankAccount()
await account.deposit(1000)
// simultaneously attempt to withdraw
async let one = account.withdraw(500)
class BankAccount {
enum BankAccountError: Error {
case insufficientFunds
}
private(set) var balance: Double = 0
func deposit(_ amount: Double) {
balance += amount
}
// 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)
}
}
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