繁体   English   中英

将JSON数组反序列化为Swift对象数组

[英]Deserialize a JSON array to a Swift array of objects

我是Swift的新手,并且无法弄清楚如何将JSON数组反序列化为Swift对象数组。 我能够将单个JSON用户反序列化为Swift用户对象,但不确定如何使用JSON用户数组。

这是我的User.swift类:

class User {
    var id: Int
    var firstName: String?
    var lastName: String?
    var email: String
    var password: String?

    init (){
        id = 0
        email = ""
    }

    init(user: NSDictionary) {
        id = (user["id"] as? Int)!
        email = (user["email"] as? String)!

        if let firstName = user["first_name"] {
            self.firstName = firstName as? String
        }

        if let lastName = user["last_name"] {
            self.lastName = lastName as? String
        }

        if let password = user["password"] {
            self.password = password as? String
        }
     }
}

这是我正在尝试反序列化JSON的类:

//single user works.
Alamofire.request(.GET, muURL/user)
         .responseJSON { response in
                if let user = response.result.value {
                    var swiftUser = User(user: user as! NSDictionary)
                }
          }

//array of users -- not sure how to do it. Do I need to loop?
Alamofire.request(.GET, muURL/users)
         .responseJSON { response in
                if let users = response.result.value {
                    var swiftUsers = //how to get [swiftUsers]?
                }
          }

最好的方法是使用Alamofire提供的通用响应对象序列化这里是一个例子:

1)在您的API管理器或单独的文件中添加扩展名

    public protocol ResponseObjectSerializable {
        init?(response: NSHTTPURLResponse, representation: AnyObject)
    }

    extension Request {
        public func responseObject<T: ResponseObjectSerializable>(completionHandler: Response<T, NSError> -> Void) -> Self {
            let responseSerializer = ResponseSerializer<T, NSError> { request, response, data, error in
                guard error == nil else { return .Failure(error!) }

                let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
                let result = JSONResponseSerializer.serializeResponse(request, response, data, error)

                switch result {
                case .Success(let value):
                    if let
                        response = response,
                        responseObject = T(response: response, representation: value)
                    {
                        return .Success(responseObject)
                    } else {
                        let failureReason = "JSON could not be serialized into response object: \(value)"
                        let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
                        return .Failure(error)
                    }
                case .Failure(let error):
                    return .Failure(error)
                }
            }

            return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
        }
    }

public protocol ResponseCollectionSerializable {
    static func collection(response response: NSHTTPURLResponse, representation: AnyObject) -> [Self]
}

extension Alamofire.Request {
    public func responseCollection<T: ResponseCollectionSerializable>(completionHandler: Response<[T], NSError> -> Void) -> Self {
        let responseSerializer = ResponseSerializer<[T], NSError> { request, response, data, error in
            guard error == nil else { return .Failure(error!) }

            let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
            let result = JSONSerializer.serializeResponse(request, response, data, error)

            switch result {
            case .Success(let value):
                if let response = response {
                    return .Success(T.collection(response: response, representation: value))
                } else {
                    let failureReason = "Response collection could not be serialized due to nil response"
                    let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
                    return .Failure(error)
                }
            case .Failure(let error):
                return .Failure(error)
            }
        }

        return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
    }
}

2)像这样更新你的模型对象:

final class User: ResponseObjectSerializable, ResponseCollectionSerializable {
    let username: String
    let name: String

    init?(response: NSHTTPURLResponse, representation: AnyObject) {
        self.username = response.URL!.lastPathComponent!
        self.name = representation.valueForKeyPath("name") as! String
    }

    static func collection(response response: NSHTTPURLResponse, representation: AnyObject) -> [User] {
        var users: [User] = []

        if let representation = representation as? [[String: AnyObject]] {
            for userRepresentation in representation {
                if let user = User(response: response, representation: userRepresentation) {
                    users.append(user)
                }
            }
        }

        return users
    }
}

3)然后你就可以这样使用它:

Alamofire.request(.GET, "http://example.com/users")
         .responseCollection { (response: Response<[User], NSError>) in
             debugPrint(response)
         }

来源: 通用响应对象序列化

有用链接: Alamofire JSON对象和集合的序列化

由于您使用Alamofire提出请求,为什么不给Hearst-DD ObjectMapper一个机会它有一个Alamofire扩展AlamofireObjectMapper 我想这会节省你的时间!

我会循环遍历它们然后将每个用户添加到一个数组(最好是VC的属性而不是实例变量),但这是一个例子。

    Alamofire.request(.GET, "YourURL/users")
        .responseJSON { response in

            if let users = response.result.value {

                for user in users {

                    var swiftUser = User(user: user as! NSDictionary)

                    //should ideally be a property of the VC
                    var userArray : [User]

                    userArray.append(swiftUser)
                }
            }
    }

您也可以尝试EVReflection https://github.com/evermeer/EVReflection它更简单,即解析JSON(从EVReflection链接获取的代码片段):

let json:String = "{
    \"id\": 24, 
    \"name\": \"Bob Jefferson\",
    \"friends\": [{
        \"id\": 29, 
        \"name\": 
        \"Jen Jackson\"}]}"

你可以使用这个类:

class User: EVObject {
    var id: Int = 0
    var name: String = ""
    var friends: [User]? = []
}

通过这种方式:

let user = User(json: json)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM