async/await
Seit Swift 5.5 gibt es strukturierte Nebenläufigkeit: Funktionen mit async können pausieren, await wartet auf ihr Ergebnis, ohne einen Thread zu blockieren.
import Foundation
func laden(_ id: Int) async -> String {
try? await Task.sleep(nanoseconds: 50_000_000) // simuliert Netzwerk
return "Nutzer \(id)"
}
func laden(mitFehler: Bool) async throws -> Int {
if mitFehler { throw URLError(.badURL) }
return 42
}
let eins = await laden(1)
print(eins)
async let a = laden(2) // parallel starten
async let b = laden(3)
print(await a, await b)
let alle = await withTaskGroup(of: String.self) { gruppe in
for id in 10...13 { gruppe.addTask { await laden(id) } }
var ergebnisse: [String] = []
for await r in gruppe { ergebnisse.append(r) }
return ergebnisse.sorted()
}
print(alle)
do { print(try await laden(mitFehler: false)); print(try await laden(mitFehler: true)) }
catch { print("Fehler:", error is URLError) }
let task = Task { await laden(99) }
print(await task.value)Ausgabe
Nutzer 1 Nutzer 2 Nutzer 3 ["Nutzer 10", "Nutzer 11", "Nutzer 12", "Nutzer 13"] 42 Fehler: true Nutzer 99
Actors: sicherer gemeinsamer Zustand
Ein Actor schützt seinen Zustand: Nur ein Zugriff gleichzeitig, der Compiler erzwingt await.
actor Konto {
private(set) var stand = 0
func einzahlen(_ betrag: Int) { stand += betrag }
}
let konto = Konto()
await withTaskGroup(of: Void.self) { gruppe in
for _ in 1...100 {
gruppe.addTask { await konto.einzahlen(10) }
}
}
print(await konto.stand)Ausgabe
1000
Apps mit SwiftUI
SwiftUI beschreibt Oberflächen deklarativ: Du sagst, wie die Ansicht zu einem Zustand aussieht, das Framework aktualisiert sie bei Änderungen.
import SwiftUI
struct ZaehlerView: View {
@State private var anzahl = 0
var body: some View {
VStack(spacing: 16) {
Text("Zähler: \(anzahl)")
.font(.largeTitle)
Button("Plus") { anzahl += 1 }
.buttonStyle(.borderedProminent)
}
.padding()
}
}
@main
struct MeineApp: App {
var body: some Scene {
WindowGroup { ZaehlerView() }
}
}| Baustein | Zweck |
|---|---|
@State | lokaler Zustand einer Ansicht |
@Binding | geteilter Zustand mit einer Unteransicht |
@Observable / ObservableObject | Datenmodell, das die Ansicht aktualisiert |
List, NavigationStack, TabView | Listen und Navigation |
SwiftData, Core Data | Persistenz |
URLSession | Netzwerk |
Daten laden und speichern (Codable)
import Foundation
struct Nutzer: Codable {
let name: String
let alter: Int
let tags: [String]
}
let json = """
{"name": "Mia", "alter": 17, "tags": ["a", "b"]}
""".data(using: .utf8)!
let nutzer = try JSONDecoder().decode(Nutzer.self, from: json)
print(nutzer.name, nutzer.alter, nutzer.tags)
let encoder = JSONEncoder()
encoder.outputFormatting = [.sortedKeys]
let ausgabe = try encoder.encode(Nutzer(name: "Tom", alter: 25, tags: []))
print(String(data: ausgabe, encoding: .utf8)!)
do {
_ = try JSONDecoder().decode(Nutzer.self, from: "{}".data(using: .utf8)!)
} catch {
print("Dekodierfehler:", error is DecodingError)
}Ausgabe
Mia 17 ["a", "b"]
{"alter":25,"name":"Tom","tags":[]}
Dekodierfehler: trueÖkosystem
- Swift Package Manager:
Package.swift, Pakete von GitHub (swift package init,swift build,swift test) - XCTest und Swift Testing (
@Test) für Tests - Vapor und Hummingbird: Webserver in Swift
- Swift on Server, Swift for Android, Embedded Swift
- Apple-Frameworks: Foundation, SwiftUI, Combine, MapKit, CoreML, ARKit
Merke
async/await,async let,TaskGroupfür nebenläufigen Codeactorschützt gemeinsamen Zustand- SwiftUI: deklarative Oberflächen mit
@State,body,some View Codablemacht JSON einfach; Swift Package Manager für Abhängigkeiten
Aufgabe
Lade mit async let drei simulierte Werte parallel und gib die Summe aus.