ios - 快速将 JSON 字符串数组转换为 NSArray
问题描述
我在某个键中收到类似这样的响应,例如:
"abc" : "[{\"ischeck\":true,\"type\":\"Some type\"},{\"ischeck\":false,\"type\":\"other type\"}]"]"
我需要将其转换为普通数组。我正在为此使用以下功能。
[{"ischeck": true, "type":"Some type"},{"ischeck": true, "type":"other type"}]
func fromJSON(string: String) throws -> [[String: Any]] {
let data = string.data(using: .utf8)!
guard let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [AnyObject] else {
throw NSError(domain: NSCocoaErrorDomain, code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid JSON"])
}
//swiftlint:disable:next force_cast
return jsonObject.map { $0 as! [String: Any] }
}
解决方案
你必须打JSONSerialization.jsonObject
两次电话。首先反序列化根对象,然后反序列化 key 的 JSON 字符串abc
。
func fromJSON(string: String) throws -> [[String: Any]] {
let data = Data(string.utf8)
guard let rootObject = try JSONSerialization.jsonObject(with: data) as? [String:String],
let innerJSON = rootObject["abc"] else {
throw NSError(domain: NSCocoaErrorDomain, code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid JSON"])
}
let innerData = Data(innerJSON.utf8)
guard let innerObject = try JSONSerialization.jsonObject(with: innerData) as? [[String:Any]] else {
throw NSError(domain: NSCocoaErrorDomain, code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid JSON"])
}
return innerObject
}
另一种更舒适的方法是使用Decodable
let jsonString = """
{"abc":"[{\\"ischeck\\":true,\\"type\\":\\"Some type\\"},{\\"ischeck\\":false,\\"type\\":\\"other type\\"}]"}
"""
struct Root : Decodable {
let abc : [Item]
private enum CodingKeys : String, CodingKey { case abc }
init(from decoder : Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let abcString = try container.decode(String.self, forKey: .abc)
abc = try JSONDecoder().decode([Item].self, from: Data(abcString.utf8))
}
}
struct Item : Decodable {
let ischeck : Bool
let type : String
}
do {
let result = try JSONDecoder().decode(Root.self, from: Data(jsonString.utf8))
print(result.abc)
} catch {
print(error)
}
推荐阅读
- javascript - 在对象字面量函数中需要等效于 switch case 的默认值
- unity3d - UnityHub 选项“Unity 编辑器文件夹”无效。想要更改 Unity 编辑器的安装位置?
- bash - 从 Bash 脚本启动时的不同版本的 Vim
- google-apps-script - 如何使用 Sheets API 在最后一列之后插入列?
- azure - 无法将存储帐户从 v1 升级到 StorageV2
- angular - ViewContainerRef 与 ngFor
- ansible - Ansible 仍然需要 root 密码?
- android - 为什么我的动态链接无法在 Play 商店安装中幸存?
- java - Java 输入编码
- javascript - 如何从节点js中的端点获取查询字符串参数