-
Data Essentials in SwiftUI
Data is a complex part of any app, but SwiftUI makes it easy to ensure a smooth, data-driven experience from prototyping to production. Discover @State and @Binding, two powerful tools that can preserve and seamlessly update your Source of Truth. We'll also show you how ObservableObject lets you connect your views to your data model. Learn about some tricky challenges and cool new ways to solve them — directly from the experts!
To get the most out of this session, you should be familiar with SwiftUI. Watch “App essentials in SwiftUI” and "Introduction to SwiftUI"Ressources
Vidéos connexes
WWDC22
WWDC21
WWDC20
-
Rechercher dans cette vidéo…
-
-
2:09 - BookCard
struct BookCard : View { let book: Book let progress: Double var body: some View { HStack { Cover(book.coverName) VStack(alignment: .leading) { TitleText(book.title) AuthorText(book.author) } Spacer() RingProgressView(value: progress) } } } -
3:35 - EditorConfig
struct EditorConfig { var isEditorPresented = false var note = "" var progress: Double = 0 mutating func present(initialProgress: Double) { progress = initialProgress note = "" isEditorPresented = true } } struct BookView: View { @State private var editorConfig = EditorConfig() func presentEditor() { editorConfig.present(…) } var body: some View { … Button(action: presentEditor) { … } … } } -
5:59 - ProgressEditor
struct EditorConfig { var isEditorPresented = false var note = "" var progress: Double = 0 } struct BookView: View { @State private var editorConfig = EditorConfig() var body: some View { … ProgressEditor(editorConfig: $editorConfig) … } } struct ProgressEditor: View { @Binding var editorConfig: EditorConfig … TextEditor($editorConfig.note) … } -
13:15 - CurrentlyReading
/// The current reading progress for a specific book. class CurrentlyReading: ObservableObject { let book: Book @Published var progress: ReadingProgress // … } struct ReadingProgress { struct Entry : Identifiable { let id: UUID let progress: Double let time: Date let note: String? } var entries: [Entry] } -
15:36 - BookView
struct BookView: View { @ObservedObject var currentlyReading: CurrentlyReading var body: some View { VStack { BookCard( currentlyReading: currentlyReading) //… ProgressDetailsList( progress: currentlyReading.progress) } } } -
17:50 - CurrentlyReading with isFinished
class CurrentlyReading: ObservableObject { let book: Book @Published var progress = ReadingProgress() @Published var isFinished = false var currentProgress: Double { isFinished ? 1.0 : progress.progress } } -
18:21 - BookView with Toggle
struct BookView: View { @ObservedObject var currentlyReading: CurrentlyReading var body: some View { VStack { BookCard( currentlyReading: currentlyReading) HStack { Button(action: presentEditor) { /* … */ } .disabled(currentlyReading.isFinished) Toggle( isOn: $currentlyReading.isFinished ) { Label( "I'm Done", systemImage: "checkmark.circle.fill") } } //… } } } -
19:58 - CoverImageLoader
class CoverImageLoader: ObservableObject { @Published public private(set) var image: Image? = nil func load(_ name: String) { // … } func cancel() { // … } deinit { cancel() } } -
20:20 - BookCoverView
struct BookCoverView: View { @StateObject var loader = CoverImageLoader() var coverName: String var size: CGFloat var body: some View { CoverImage(loader.image, size: size) .onAppear { loader.load(coverName) } } } -
25:36 - ReadingListViewer (Bad)
struct ReadingListViewer: View { var body: some View { NavigationView { ReadingList() Placeholder() } } } struct ReadingList: View { @ObservedObject var store = ReadingListStore() var body: some View { // ... } } -
26:39 - ReadingListViewer (Good)
struct ReadingListViewer: View { var body: some View { NavigationView { ReadingList() Placeholder() } } } struct ReadingList: View { @StateObject var store = ReadingListStore() var body: some View { // ... } } -
30:52 - App-wide Source of Truth
@main struct BookClubApp: App { @StateObject private var store = ReadingListStore() var body: some Scene { WindowGroup { ReadingListViewer(store: store) } } } -
32:43 - SceneStorage
struct ReadingListViewer: View { @SceneStorage("selection") var selection: String? var body: some View { NavigationView { ReadingList(selection: $selection) BookDetailPlaceholder() } } } -
33:49 - AppStorage
struct BookClubSettings: View { @AppStorage("updateArtwork") private var updateArtwork = true @AppStorage("syncProgress") private var syncProgress = true var body: some View { Form { Toggle(isOn: $updateArtwork) { //... } Toggle(isOn: $syncProgress) { //... } } } }
-