将JSON数组反序列化为Swift对象数组 [英] Deserialize a JSON array to a Swift array of objects

查看:127
本文介绍了将JSON数组反序列化为Swift对象数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to Swift, and am not able to figure out how to deserialize a JSON array to an array of Swift objects. I'm able to deserialize a single JSON user to a Swift user object fine, but just not sure how to do it with a JSON array of users.

这是我的User.swift类:

Here is my User.swift class:

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:

Here's the class where I'm trying to deserialize the 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 提供的通用响应对象序列化这里有一个例子:

The best approach is the use Generic Response Object Serialization provided by Alamofire here is an example :

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

1) Add the extension in your API Manager or on a separate file

    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)像这样更新你的模型对象:

2) update your model object like this:

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)然后你就可以这样使用它:

3) then you can use it like that :

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

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

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

这篇关于将JSON数组反序列化为Swift对象数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆