【问题标题】:Append things to Array at launching在启动时将内容附加到 Array
【发布时间】:2020-11-29 11:51:15
【问题描述】:

您好,对以下代码有疑问:

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。

【问题讨论】:

    标签: ios swift swiftui nsuserdefaults swiftui-list


    【解决方案1】:

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

    value 参数只能是属性列表对象:NSData、NSString、NSNumber、NSDate、NSArray 或 NSDictionary。对于 NSArray 和 NSDictionary 对象,它们的内容必须是属性列表对象。

    see full documentation

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

    您的问题可以使用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() ?? []
    

    【讨论】:

    • @zeytin 据我了解,问题中提供的 sn-p 中处理用户默认值的代码将无法按预期工作。
    • 你能告诉我如何在 lauch 时将 savedItems 添加到我的 listItems 中
    • 我已经更新了我的答案 :) 现在您可以在 UserDefaults 实例本身上使用辅助方法将项目直接加载到 listItems
    猜你喜欢
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 2017-12-20
    相关资源
    最近更新 更多