如何使用 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_iderror 的值。但是我不知道如何在同一个 NSObject 类中初始化usersinfo 的数组。

现在我像这样初始化 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
    

现在的问题是我不知道如何初始化 usersinfo 字典中的数据。我应该如何安排它以及如何在其他类中使用它

请举个例子。

【问题讨论】:

@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 中的多个字典的主要内容,如果未能解决你的问题,请参考以下文章

包含 SwiftyJSON 时返回数百个错误

如何使用 SwiftyJson 解析 JSON

如何使用 SwiftyJSON 获取 json 数据的值

Swift:如何使用 cocoapods 安装 SwiftyJson?

swift、Alamofire、SwiftyJSON:如何解析 arrayObject

使用 SwiftyJSON 反序列化时如何添加对象数组