Swift 在UserDefaults中设置对象数组

Swift 在UserDefaults中设置对象数组,swift,nsuserdefaults,swifty-json,userdefaults,Swift,Nsuserdefaults,Swifty Json,Userdefaults,如何在UserDefaults中设置并稍后获取json对象数组 我的应用程序在尝试按以下方式设置时崩溃: import SwiftyJSON var finalArray = [JSON]() UserDefaults.standard.set(finalArray, forKey: "attemptedArray") 我的数据如下所示: [{ "marked" : 3, "attempted" : true, "correct" : 3, "subject" : 1,

如何在
UserDefaults
中设置并稍后获取json对象数组

我的应用程序在尝试按以下方式设置时崩溃:

import SwiftyJSON
var finalArray = [JSON]()

UserDefaults.standard.set(finalArray, forKey: "attemptedArray")
我的数据如下所示:

[{
  "marked" : 3,
  "attempted" : true,
  "correct" : 3,
  "subject" : 1,
  "status" : true,
  "question" : 219,
  "answer" : 32931,
  "time" : 15,
  "score" : 5,
  "chapter" : 26
}, {
  "marked" : 4,
  "attempted" : true,
  "correct" : 4,
  "subject" : 1,
  "status" : true,
  "question" : 550,
  "answer" : 34256,
  "time" : 23,
  "score" : 10,
  "chapter" : 26
}, {
  "marked" : 1,
  "attempted" : true,
  "correct" : 1,
  "subject" : 1,
  "status" : true,
  "question" : 566,
  "answer" : 34317,
  "time" : 33,
  "score" : 14,
  "chapter" : 26
}]

阅读:-

UserDefaults
无法保存SwiftyJSON的
JSON
类型。您必须保存他们支持的某种类型,在这种情况下,您要查找
数据

无论如何,要将
数据
保存到
用户默认值
并不是最好的,您应该将
数据
保存到其他地方的文件中。要实现这一点,可以使用
FileManager


因此,为您的数据创建自定义模型,而不是使用
JSON
,并对自定义模型采用
Codable

struct Model: Codable {
    var marked, correct, subject, question, answer, time, score, chapter: Int
    var attempted, status: Bool
}
然后,您应该使用此
模型
作为数组中的元素类型(注意,然后您需要使用
jsondeconder
(见下文))对
数据
中的响应进行解码)

然后,您可以使用
jsonecoder
将模型数组编码为
数据
,您可以将其写入某个文件

do {
    let encoded = try JSONEncoder().encode(finalArray)
    let preferencesDirectoryURL = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!.appendingPathComponent("Preferences", isDirectory: true)
    let fileURL = preferencesDirectoryURL.appendingPathComponent("fileName.json")
    try encoded.write(to: fileURL)
} catch { print(error) }
JSONDecoder
,用于解码保存文件中的
数据

do {
    let preferencesDirectoryURL = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!.appendingPathComponent("Preferences", isDirectory: true)
    let fileURL = preferencesDirectoryURL.appendingPathComponent("fileName.json")

    if let data = try? Data(contentsOf: fileURL) {
        let decoded = try JSONDecoder().decode([Model].self, from: data)
    }
} catch { print(error) }

出于某些原因,不建议在NSuser默认设置中保存大量数据:

  • 如果要删除阵列的某些单元格,则需要从nsuser默认值中删除它们。只有将它们保存为 数组,而不是作为个体

  • 如果每次删除或添加一个项目时选择将它们保存为数组,则需要保存所有项目。如果阵列很大,可能需要一段时间

  • 任何人都可以访问NSuser默认设置。所以它不安全


  • 无论如何,我真的建议使用核心数据。它省去了我提到的所有麻烦

    “我的应用程序崩溃”,错误消息是什么
    JSON
    似乎不符合NSCoding,您无法将任何需要的内容保存到
    UserDefaults
    (您需要将其转换为允许的类型)。检查它的文档。它无法保存用户创建的类的对象。。。您正在保存“JSON”的对象,将其转换为字典,然后您可以保存名为
    finalArr
    的变量,但您正在设置
    finalArray
    。请使用正确的变量。您可以将其转换为
    [[String:Any]]
    ?这是滥用用户默认值。请不要滥用用户默认值。使用类型为的未捕获异常终止NSException@DeepakVerma,请参阅更新的答案。根据iOS 12,您需要使用最新的语法。可编码的实现很好。它不是将数据保存到UserDefaults。这意味着只存储应用程序的界面状态。它不是用来存储一般应用程序数据的。您可以将数据写入磁盘到一个单独的文件
    .json
    (这只是一个格式正确的简单文本文件)中,该文件与UserDefaults用于存储其首选项文件
    库/首选项
    的目录相同
    do {
        let encoded = try JSONEncoder().encode(finalArray)
        let preferencesDirectoryURL = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!.appendingPathComponent("Preferences", isDirectory: true)
        let fileURL = preferencesDirectoryURL.appendingPathComponent("fileName.json")
        try encoded.write(to: fileURL)
    } catch { print(error) }
    
    do {
        let preferencesDirectoryURL = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!.appendingPathComponent("Preferences", isDirectory: true)
        let fileURL = preferencesDirectoryURL.appendingPathComponent("fileName.json")
    
        if let data = try? Data(contentsOf: fileURL) {
            let decoded = try JSONDecoder().decode([Model].self, from: data)
        }
    } catch { print(error) }