100 Days of SwiftUI(DAY 53(Project11 part 1))

Core Data
学習するアプリ開発スキルは、Appleのフレームワークの1つであるCore Dataです。読み取り、書き込み、フィルタリング、並べ替えなど、データベース内のオブジェクトの管理を担当し、iOS、macOSなどのすべてのアプリ開発で非常に重要です。

カナダのソフトウェア開発者Rob Pike – Goプログラミング言語の作成者であり、Unixを開発したチームのメンバーであり、UTF-8の共同作成者であり、作者でもあります–データについてこれを書いた:
「データが支配します。適切なデータ構造を選択し、適切に整理した場合、アルゴリズムはほとんど常に自明です。アルゴリズムではなく、データ構造がプログラミングの中心です。」

@Bindingを使用したカスタムコンポーネントの作成
Creating a custom component with @Binding

Bookworm
重要:[コアデータを使用する]チェックボックスを必ずオンにしてください。

@Binding
1つのビューのプロパティをいくつかの基礎となるモデルデータに接続できます。
ビュー内に変更可能な値を作成し、実際には他の場所からの他の値を指すようにすることです。
他のビューと直接インターフェイスできるプロパティを公開します。

import SwiftUI
//-----------------------
struct PushButton: View {
    let title: String
    //@State var isOn: Bool
    @Binding var isOn: Bool

    var onColors = [Color.yellow,Color.red]
    var offColors = [Color(white: 0.6), Color(white: 0.4)]

    var body: some View {
        Button(title) {
            self.isOn.toggle()
        }
        .padding()
        .background(LinearGradient(gradient: Gradient(colors: isOn ? onColors : offColors), startPoint: .top, endPoint: .bottom))
        .foregroundColor(.white)
        .clipShape(Capsule())
        .shadow(radius: isOn ? 0 : 5)
    }
}
//-----------------------
struct ContentView: View {
    @State private var rememberMe = false

    var body: some View {
        VStack {
            //PushButton(title: "Remember Me", isOn: rememberMe)
            PushButton(title: "Remember Me", isOn: $rememberMe)
            Text(rememberMe ? "On" : "Off")
        }
    }
}

AnyViewタイプの消去でサイズクラスを使用する
Using size classes with AnyView type erasure

コンパクト」と「レギュラー」と呼ばれる水平方向と垂直方向の2つのサイズクラスしかないということです。
AnyView特に必要がない限り、通常は回避するのが最善です。

両方のスタックをAnyViewと呼ばれる新しいビュータイプにラップしたことです。これは、タイプ消去ラッパーと呼ばれています。

import SwiftUI

struct ContentView: View {
    @Environment(\.horizontalSizeClass) var sizeClass

    var body: some View {
        if sizeClass == .compact {
            return AnyView(VStack {
                Text("Active size class:")
                Text("COMPACT")
            }
            .font(.largeTitle))
        } else {
            return AnyView(HStack {
                Text("Active size class:")
                Text("REGULAR")
            }
            .font(.largeTitle))
        }
    }
}

Core DataとSwiftUIを組み合わせる方法
How to combine Core Data and SwiftUI

CodableとUserDefaultsよりもはるかに高度です。CoreDataはデータのソートとフィルタリングが可能であり、はるかに大きなデータを扱うことができます。格納できるデータの量に事実上制限はありません。さらに優れた点として、Core Dataは、データ検証、データの遅延読み込み、元に戻すとやり直しなど、本当に必要なときに備えて、あらゆる種類の高度な機能を実装しています。

Core Dataの設定には2つのステップが必要です:永続的なコンテナーと呼ばれるものを作成します。これは、デバイスストレージから実際のデータをロードして保存し、それをSwiftUI環境に注入して、すべてのビューがアクセスできるようにします。これらの手順はどちらも、Xcodeテンプレートによって既に行われています。

残っているのは、Core Dataに格納するデータと、それを読み戻す方法を決定することです。

不具合発生!!
(Bookworm.xcdatamodeld) → (Student entity) → (Codegen Manual None) → (Editor) → (create nsobject class)
により解決!!
更に
SwiftUI CoreData crashes preview


import SwiftUI
import CoreData

struct ContentView: View {
@Environment(\.managedObjectContext) var moc
    
@FetchRequest(entity: Student.entity(), sortDescriptors: []) var students: FetchedResults<Student>
    
    
    var body: some View {
        VStack {
            List {
                ForEach(students, id: \.id) { student in
                    Text(student.name ?? "Unknown")
                }
            }
            Button("Add") {
                let firstNames = ["Ginny", "Harry", "Hermione", "Luna", "Ron"]
                let lastNames = ["Granger", "Lovegood", "Potter", "Weasley"]

                let chosenFirstName = firstNames.randomElement()!
                let chosenLastName = lastNames.randomElement()!

                // more code to come
                let student = Student(context: self.moc)
                student.id = UUID()
                student.name = "\(chosenFirstName) \(chosenLastName)"
                try? self.moc.save()
            }
        }
    }
}