如何使用 SwiftyJson 在 1 个 NSObject 中初始化 json 中的多个字典
Posted
技术标签:
【中文标题】如何使用 SwiftyJson 在 1 个 NSObject 中初始化 json 中的多个字典【英文标题】:How to initialize multiple dictionary in json in 1 NSObject using SwiftyJson 【发布时间】:2018-02-23 10:54:29 【问题描述】:我的 API 响应是这样的
"error": false,
"id": "6",
"user_id": 7,
"users": [
"user_id": 1,
"username": "spiderman"
,
"user_id": 7,
"username": "wonderwoman"
],
"info": [
"id": 471,
"message": "abc",
"age": 10,
]
我知道如何在 NSOject 中初始化 id
,user_id
和 error
的值。但是我不知道如何在同一个 NSObject 类中初始化users
和info
的数组。
现在我像这样初始化 JSON
import UIKit
import SwiftyJSON
class MyItem: NSObject
var userId : Int
var error : Bool
var id : Int
init?(dict: [String :JSON])
self.id = dict["id"]?.int ?? 0
self.error = dict["error"]?.bool ?? false
self.userId = dict["userId"]?.int ?? 0
现在的问题是我不知道如何初始化 users
和 info
字典中的数据。我应该如何安排它以及如何在其他类中使用它
请举个例子。
【问题讨论】:
@Venkat 那么如何访问里面的数据呢?? 【参考方案1】:如下使用,
根类:-
import Foundation
import SwiftyJSON
class RootClass : NSObject, NSCoding
var error : Bool!
var id : String!
var info : [Info]!
var userId : Int!
var users : [User]!
/**
* Instantiate the instance using the passed json values to set the properties values
*/
init(fromJson json: JSON!)
if json.isEmpty
return
error = json["error"].boolValue
id = json["id"].stringValue
info = [Info]()
let infoArray = json["info"].arrayValue
for infoJson in infoArray
let value = Info(fromJson: infoJson)
info.append(value)
userId = json["user_id"].intValue
users = [User]()
let usersArray = json["users"].arrayValue
for usersJson in usersArray
let value = User(fromJson: usersJson)
users.append(value)
/**
* Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
*/
func toDictionary() -> [String:Any]
let dictionary = [String:Any]()
if error != nil
dictionary["error"] = error
if id != nil
dictionary["id"] = id
if info != nil
var dictionaryElements = [[String:Any]]()
for infoElement in info
dictionaryElements.append(infoElement.toDictionary())
dictionary["info"] = dictionaryElements
if userId != nil
dictionary["user_id"] = userId
if users != nil
var dictionaryElements = [[String:Any]]()
for usersElement in users
dictionaryElements.append(usersElement.toDictionary())
dictionary["users"] = dictionaryElements
return dictionary
/**
* NSCoding required initializer.
* Fills the data from the passed decoder
*/
@objc required init(coder aDecoder: NSCoder)
error = aDecoder.decodeObject(forKey: "error") as? Bool
id = aDecoder.decodeObject(forKey: "id") as? String
info = aDecoder.decodeObject(forKey: "info") as? [Info]
userId = aDecoder.decodeObject(forKey: "user_id") as? Int
users = aDecoder.decodeObject(forKey: "users") as? [User]
/**
* NSCoding required method.
* Encodes mode properties into the decoder
*/
func encode(with aCoder: NSCoder)
if error != nil
aCoder.encode(error, forKey: "error")
if id != nil
aCoder.encode(id, forKey: "id")
if info != nil
aCoder.encode(info, forKey: "info")
if userId != nil
aCoder.encode(userId, forKey: "user_id")
if users != nil
aCoder.encode(users, forKey: "users")
用户类:-
import Foundation
import SwiftyJSON
class User : NSObject, NSCoding
var userId : Int!
var username : String!
/**
* Instantiate the instance using the passed json values to set the properties values
*/
init(fromJson json: JSON!)
if json.isEmpty
return
userId = json["user_id"].intValue
username = json["username"].stringValue
/**
* Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
*/
func toDictionary() -> [String:Any]
let dictionary = [String:Any]()
if userId != nil
dictionary["user_id"] = userId
if username != nil
dictionary["username"] = username
return dictionary
/**
* NSCoding required initializer.
* Fills the data from the passed decoder
*/
@objc required init(coder aDecoder: NSCoder)
userId = aDecoder.decodeObject(forKey: "user_id") as? Int
username = aDecoder.decodeObject(forKey: "username") as? String
/**
* NSCoding required method.
* Encodes mode properties into the decoder
*/
func encode(with aCoder: NSCoder)
if userId != nil
aCoder.encode(userId, forKey: "user_id")
if username != nil
aCoder.encode(username, forKey: "username")
信息类:-
import Foundation
import SwiftyJSON
class Info : NSObject, NSCoding
var age : Int!
var id : Int!
var message : String!
/**
* Instantiate the instance using the passed json values to set the properties values
*/
init(fromJson json: JSON!)
if json.isEmpty
return
age = json["age"].intValue
id = json["id"].intValue
message = json["message"].stringValue
/**
* Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
*/
func toDictionary() -> [String:Any]
let dictionary = [String:Any]()
if age != nil
dictionary["age"] = age
if id != nil
dictionary["id"] = id
if message != nil
dictionary["message"] = message
return dictionary
/**
* NSCoding required initializer.
* Fills the data from the passed decoder
*/
@objc required init(coder aDecoder: NSCoder)
age = aDecoder.decodeObject(forKey: "age") as? Int
id = aDecoder.decodeObject(forKey: "id") as? Int
message = aDecoder.decodeObject(forKey: "message") as? String
/**
* NSCoding required method.
* Encodes mode properties into the decoder
*/
func encode(with aCoder: NSCoder)
if age != nil
aCoder.encode(age, forKey: "age")
if id != nil
aCoder.encode(id, forKey: "id")
if message != nil
aCoder.encode(message, forKey: "message")
【讨论】:
【参考方案2】:最好的方法是为用户和信息创建 2 个不同的类,如下所示:
class MyItem : NSObject
var error : Bool!
var id : String!
var info : [Info]!
var userId : Int!
var users : [User]!
init(fromJson json: JSON!)
if json == nil
return
error = json["error"].boolValue
id = json["id"].stringValue
info = [Info]()
let infoArray = json["info"].arrayValue
for infoJson in infoArray
let value = Info(fromJson: infoJson)
info.append(value)
userId = json["user_id"].intValue
users = [User]()
let usersArray = json["users"].arrayValue
for usersJson in usersArray
let value = User(fromJson: usersJson)
users.append(value)
class User : NSObject
var userId : Int!
var username : String!
init(fromJson json: JSON!)
if json == nil
return
userId = json["user_id"].intValue
username = json["username"].stringValue
class Info : NSObject
var age : Int!
var id : Int!
var message : String!
init(fromJson json: JSON!)
if json == nil
return
age = json["age"].intValue
id = json["id"].intValue
message = json["message"].stringValue
通过这样做,您将能够直接访问用户的值和信息,例如:MyItem.users[index].userId
【讨论】:
【参考方案3】:这样做,
class MyItem: NSObject
var userId : Int
var error : Bool
var id : Int
var users : [[String:Any]] = []
var info : [[String:Any]] = []
init?(dict: [String :JSON])
self.id = dict["id"]?.int ?? 0
self.error = dict["error"]?.bool ?? false
self.userId = dict["userId"]?.int ?? 0
self.users = dict["users"] ?? []
self.info = dict["info"] ?? []
【讨论】:
【参考方案4】:无意冒犯SwiftyJSON
的开发人员,它是一个很棒的库,但在 Swift 4 中解码 JSON SwiftyJSON
已经过时了。
使用Decodable
协议,您无需任何额外代码即可解码 JSON。
创建一个包含两个子结构的结构,编码键只需要将snake_case映射到camelCase。
struct MyItem: Decodable
private enum CodingKeys: String, CodingKey case userId = "user_id", error, id, users, info
let userId : Int
let error : Bool
let id : String
let users : [User]
let info : [Info]
struct User : Decodable
private enum CodingKeys: String, CodingKey case userId = "user_id", username
let userId : Int
let username : String
struct Info : Decodable
let message : String
let id, age : Int
现在解码 JSON
let jsonString = """
"error": false,
"id": "6",
"user_id": 7,
"users": ["user_id": 1, "username": "spiderman","user_id": 7,"username": "wonderwoman"],
"info": ["id": 471,"message": "abc", "age": 10]
"""
do
let data = Data(jsonString.utf8)
let decoder = JSONDecoder()
let result = try JSONDecoder().decode(MyItem.self, from: data)
for user in result.users
print(user.userId, user.username)
catch print(error)
【讨论】:
那么先生怎么用呢? 我更新了答案以打印users
中的所有属性。使用完成。编译器会向您显示可用的属性。以上是关于如何使用 SwiftyJson 在 1 个 NSObject 中初始化 json 中的多个字典的主要内容,如果未能解决你的问题,请参考以下文章
Swift:如何使用 cocoapods 安装 SwiftyJson?