在启动时将内容附加到 Array

Append things to Array at launching

您好,请问以下代码:

struct ContentView: View {

      @State private var listItems = [Item]()
      let savedItems = UserDefaults.standard.string(forKey: "Items") ?? "error"
      var body: some View {
        NavigationView{

            List{
              ForEach(listItems){ item in
                Text(item.name)
              }
              NavigationLink(
                destination: AddView(listItems: $listItems),
                label: {
                  Text("                 Add")
                    .foregroundColor(.blue)
                })
            }
            .navigationBarTitle("MyApp")
        }
      }
    }

struct AddView: View {
      @State var text:String = ""
      @Binding var listItems: [Item]

      var body: some View {
        VStack{
          TextField("Name", text: $text).padding().background(Color(.systemGray5)).frame(width: 400,alignment: .center).cornerRadius(20)

          Button(action: {
            listItems.append(Item(name: text, image: "Gif"))
            print(listItems)
            UserDefaults.standard.set(listItems, forKey: "Items")
          }, label: {
            Text("Add")
          })
        }
      }
    }

如果我在 AddView 中追加某些内容,我想将其保存在 UserDefaults 中并在应用程序启动时自动追加。但我不知道该怎么做。你能帮助我吗 ? PS:我正在使用 AppDelegate 和 SceneDelegate。

要在 UserDefaults 中保存某些内容,它需要是以下任一内容:

The value parameter can be only property list objects: NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects.

see full documentation

您正在尝试分配 Item 个对象的数组,虽然保存数组非常好,但该数组的元素类型也需要是文档中提到的类型之一。

您的问题可以使用 Codable 一致性来解决。

使用 Codable

扩展您的项目类型
struct Item: Codable {
    /// your implementation
}

将编码项目保存到 UserDefaults

extension UserDefaults {
    func saveItems(_ items: [Item]) {
        let encoder = JSONEncoder()
        if let data = try? encoder.encode(items) {
            set(data, forKey: "Items")
        }
    }
}

只要您想保存 listItems 数组,随时调用此方法即可。

UserDefaults.standard.saveItems(listItems)

从 UserDefaults 中读取存储的项目

extension UserDefaults {
    func readItems() -> [Item]? {
        guard let data = value(forKey: "Items") as? Data else {
            return nil
        }
        let decoder = JSONDecoder()
        return try? decoder.decode([Item].self, from: data)
    }
}

使用此方法,您可以在需要时延迟加载项目

@State private var listItems = UserDefaults.standard.readItems() ?? []