在UserDefaults中设置对象数组

时间:2019-02-18 11:27:44

标签: 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,
  "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
}]

3 个答案:

答案 0 :(得分:2)

UserDefaults无法保存SwiftyJSON的JSON类型。您必须保存一些他们支持的类型,在这种情况下,您正在寻找Data

无论如何,将Data保存到UserDefaults并不是最好的方法,您应该保存Data并将其保存在其他地方。为此,您可以使用FileManager


因此,请为您的数据创建自定义模型,而不要使用JSON并将Codable用作自定义模型

struct Model: Codable {
    var marked, correct, subject, question, answer, time, score, chapter: Int
    var attempted, status: Bool
}

然后,您应该将此Model用作数组内元素的类型(请注意,然后您需要使用DataJSONDecoder的响应进行解码(见下文))< / p>

var finalArray = [Model]()

然后您可以使用JSONEncoder将模型数组编码为Data,然后将其写入某些文件

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用于从保存的文件中解码Data

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) }

答案 1 :(得分:0)

do{
            try let data = NSKeyedArchiver.archivedData(withRootObject: finalArray, requiringSecureCoding: false)
    UserDefaults.standard.set(data, forKey: "attemptedArray")
        }catch{
            print("Print exception here")
        }

阅读:-Property List Programming Guide

答案 2 :(得分:0)

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

  1. 如果要删除阵列的某些单元格,则需要从nsuser默认设置中删除它们。仅将它们另存为 数组而不是个人。

  2. 如果每次删除或添加一项时都选择将它们另存为数组,则需要保存所有它们。如果数组很大,可能要花一些时间

  3. 任何人都可以访问NSuser默认设置。因此不安全

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