Swiftで通知ページリストデータを永続化

NotificationsView.swift
構造体にCondableとIdentifiableを追加。項目にidを追加。 fruitsを定義する際に空初期値をセット。
NavigationViewを追加。onAppear時にloadUd関数を呼出。
VStackにタイトル追加。
ForEachの書き方をindexを使わない方法に変更。
行タップ時にFruitを再作成し、saveUd関数を呼出。
loadUd関数で、UserDefaultsからtabapp_valueをキーにしてデータ取得。
データがない場合は構造体配列に初期値をセット。
データがある場合はPropertyListDecoderでdecodeして構造体配列にセット。
saveUd関数で、構造体配列をPropertyListEncoderでencodeして、tabapp_valueをキーにしてUserDefaultsに保存。
struct Fruit {
    var kind: String
    var checked: Bool

    init(_ kind: String, checked: Bool) {
        self.kind = kind
        self.checked = checked
    }
}

struct NotificationsView: View {
    @State var fruits:[Fruit] = [
        Fruit("やまぶどう", checked: true),
        Fruit("からすうり", checked: true),
        Fruit("へびいちご", checked: true),
        Fruit("じゅずだま", checked: true)
    ]

    var body: some View {
        VStack{
            List {
                ForEach(0 ..< fruits.count) { index in
                    HStack {
                        Text(self.fruits[index].kind)
                        Spacer()
                        Text(self.fruits[index].checked ? "通知あり" : "通知なし")
                        Image(self.fruits[index].checked ? "toggleon" : "toggleoff")
                    }
                    .contentShape(Rectangle())
                    .onTapGesture {
                        self.fruits[index].checked.toggle()
                    }
                }
             }
        }
    }
}
struct Fruit: Codable,Identifiable {
    let id: Int
    var kind: String
    var checked: Bool

    init(_ id: Int, kind: String, checked: Bool) {
        self.id = id
        self.kind = kind
        self.checked = checked
    }
}

struct NotificationsView: View {
    @State private var fruits:[Fruit] = []
    @State private var chk:Bool = false
    var body: some View {
        NavigationView {
            VStack{
                List {
                    ForEach(self.fruits) { fruit in
                        HStack{
                            Text(fruit.kind)
                            Spacer()
                            Text(fruit.checked ? "通知あり" : "通知なし")
                            Image(fruit.checked ? "toggleon" : "toggleoff")
                        }
                        .contentShape(Rectangle())
                        .onTapGesture {
                            self.chk = fruit.checked
                            self.chk.toggle()
                            self.fruits[fruit.id] = Fruit(fruit.id,kind:fruit.kind,checked:self.chk)
                            self.saveUd()
                        }
                    }
                }
            }
            .navigationBarTitle("設定")
        }
        .onAppear (perform: loadUd)
    }

    private func loadUd() {
        if let ud = UserDefaults.standard.value(forKey: "tabapp_value") as? Data {
            if let fruitsList = try? PropertyListDecoder().decode(Array<Fruit>.self, from: ud) {
                self.fruits = fruitsList
            }
        }else {
          self.fruits = [Fruit(0,kind:"やまぶどう",checked:true),
                             Fruit(1,kind:"からすうり",checked:true),
                             Fruit(2,kind:"へびいちご",checked:true),
                             Fruit(3,kind:"じゅずだま",checked:true)]
        }
    }
    private func saveUd() {
      UserDefaults.standard.set(try? PropertyListEncoder().encode(self.fruits), forKey: "tabapp_value")
    }
}
Codableは構造体をシリアルにして、UserDefaultsに保存するため、
Identifiableはループするため。

[Product]-[Run]実行
左上のTabApplicationで戻って、Notificationsを選択。
通知設定状況を変化させる。
Home選択でWebを表示。アプリを終了
アプリを起動してWebを表示。
左上のTabApplicationで戻って、Notificationsを選択。
変化させた通知設定状況が表示される。