Swift 以用户默认值保存JSON中的数组,并将数组值读回

Swift 以用户默认值保存JSON中的数组,并将数组值读回,swift,xcode,Swift,Xcode,我正在检索具有以下结构的JSON dict: "SITES": [ { "NAME": “ALICE LANE”, "WEBSITEAPPID": “XYZ” } ] } 我将其直接保存到用户默认值中,如下所示: UserDefaults.standard.set(JSON(dict as Any)["SITES"].stringValue, forKey: "adminSites") 我知道JSON中有数据,因为下面的代码提供了两行数组数据: if le

我正在检索具有以下结构的JSON dict:

"SITES": [
    {
    "NAME": “ALICE LANE”,
    "WEBSITEAPPID": “XYZ”
    }
  ]
}
我将其直接保存到用户默认值中,如下所示:

UserDefaults.standard.set(JSON(dict as Any)["SITES"].stringValue, forKey: "adminSites")
我知道JSON中有数据,因为下面的代码提供了两行数组数据:

if let arraySites = dict?["SITES"] as? [[String: Any]] {
  for sitesDetails in arraySites {
    print(sitesDetails["NAME"] as Any)
    print(sitesDetails["WEBSITEAPPID"] as Any)
  }
}
当我尝试打印用户默认数据计数时,得到0

let defaultAdminSites = defaults.object(forKey: "adminSites") as? [String] ?? [String]()
print(defaultAdminSites.count)

为什么我得到0个结果?如果我为[“NAME”]和[“WEBSITEAPPID”]获取了数组行详细信息,那么如何获取这些详细信息?

UserDefault Save Json响应

let result = jsonDict["SITES"] as? NSArray ?? []

let data = try! NSKeyedArchiver.archivedData(withRootObject: result, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "adminSites")
获取用户默认数据

let result = UserDefaults.standard.data(forKey: "adminSites")
    if result != nil{
      let data = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(result!) as? NSArray ?? []
      print("Current User Details : - \(data)")
}

UserDefault保存Json响应

let result = jsonDict["SITES"] as? NSArray ?? []

let data = try! NSKeyedArchiver.archivedData(withRootObject: result, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "adminSites")
获取用户默认数据

let result = UserDefaults.standard.data(forKey: "adminSites")
    if result != nil{
      let data = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(result!) as? NSArray ?? []
      print("Current User Details : - \(data)")
}

我建议使用模型对象和
Codable
来避免所有这些强制转换:

struct Model: Codable {
    let sites: [Site]

    enum CodingKeys: String, CodingKey {
        case sites = "SITES"
    }
}

struct Site: Codable {
    let name, websiteAppid: String

    enum CodingKeys: String, CodingKey {
        case name = "NAME"
        case websiteAppid = "WEBSITEAPPID"
    }
}

// write to defaults
let model = Model(sites: [Site(name: "foo", websiteAppid: "bar")])
do {
    let siteData = try JSONEncoder().encode(model)
    UserDefaults.standard.set(siteData, forKey: "adminSites")
} catch {
    print(error)
}

// read from defaults
if let siteData = UserDefaults.standard.data(forKey: "adminSites") {
    do {
        let model = try JSONDecoder().decode(Model.self, from: siteData)
        for site in model.sites {
            print(site.name, site.websiteAppid)
        }
    } catch {
        print(error)
    }
}

我建议使用模型对象和
Codable
来避免所有这些强制转换:

struct Model: Codable {
    let sites: [Site]

    enum CodingKeys: String, CodingKey {
        case sites = "SITES"
    }
}

struct Site: Codable {
    let name, websiteAppid: String

    enum CodingKeys: String, CodingKey {
        case name = "NAME"
        case websiteAppid = "WEBSITEAPPID"
    }
}

// write to defaults
let model = Model(sites: [Site(name: "foo", websiteAppid: "bar")])
do {
    let siteData = try JSONEncoder().encode(model)
    UserDefaults.standard.set(siteData, forKey: "adminSites")
} catch {
    print(error)
}

// read from defaults
if let siteData = UserDefaults.standard.data(forKey: "adminSites") {
    do {
        let model = try JSONDecoder().decode(Model.self, from: siteData)
        for site in model.sites {
            print(site.name, site.websiteAppid)
        }
    } catch {
        print(error)
    }
}


您可以将响应转换为数据以将其保存到用户默认值中。您的错误是
stringValue
,因为
SITES
是您必须写入的数组
[“SITES”]。arrayValue
,但是,按照Gereon的回答,放弃
SwiftyJSON
,转而选择
Codable
。当您保存到UserDefaults时,您尝试使用
stringValue
,它返回一个
字符串
,但当您从UserDefaults读取时,您尝试将其转换为
[String]
,这是一个字符串数组。您可以将响应转换为数据以将其保存到用户默认值中。您的错误是
stringValue
,因为
SITES
是您必须写入的数组
[“SITES”]。arrayValue
,但是,按照Gereon的回答,放弃
SwiftyJSON
,转而选择
Codable
。当您保存到UserDefaults时,您尝试使用
stringValue
,它返回一个
字符串
,但当您从UserDefaults读取时,您尝试将其转换为
[String]
,这是一个字符串数组。Objective-c-ish
NSDictionary
–这是错误的,因为对象是数组–对于Swift中的简单JSON数据,不建议使用
NSKeyed(Un)Archiver
。@vadian如果您喜欢数组中的JSON响应,可以使用贴花数组。在获取nsdictionary数据的json响应中,我声明了nsdictionary。我的代码有什么问题,为什么我的答案是否决票?正如我在第一条评论中所说的,不要使用NS。。。在Swift中的集合类型,您的代码根本不起作用,因为key
SITES
的对象是数组,而
NSKeyedUnarchiver
不适用于Swift.Objective-c-ish
NSDictionary
中的JSON等轻量级数据,因为对象是数组,这是错误的,并且
NSKeyed(Un)对于Swift中的简单JSON数据,不建议使用Archiver
。@vadian如果您喜欢数组中的JSON响应,可以使用贴花数组。在获取nsdictionary数据的json响应中,我声明了nsdictionary。我的代码有什么问题,为什么我的答案是否决票?正如我在第一条评论中所说的,不要使用NS。。。在Swift中的集合类型,您的代码不起作用,因为key
SITES
的对象是数组,
NSKeyedUnarchiver
不适用于Swift中的JSON等轻量级数据。谢谢@Gereon。我的JSON(dict as Any)[“SITES”]在上面的代码中放在哪里?更新了我的答案以包含打印值。我需要在该结构中填充我的JSON结果,因为它现在正在打印您的条目:FOO和BAR?是的,
let model=model(…)
行只是编写部分的一个示例。谢谢@Gereon。我的JSON(dict as Any)[“SITES”]在上面的代码中放在哪里?更新了我的答案以包含打印值。我需要在该结构中填充我的JSON结果,因为它现在正在打印您的条目:FOO和BAR?是的,
let model=model(…)
行只是编写部分的一个示例。