首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift 4可编程序阵列

Swift 4可编程序阵列
EN

Stack Overflow用户
提问于 2017-08-29 00:07:10
回答 4查看 21.2K关注 0票数 17

所以我有一个API路由,它返回一个JSON对象数组。例如:

代码语言:javascript
复制
[
    {"firstname": "Tom", "lastname": "Smith", "age": 31},
    {"firstname": "Bob", "lastname": "Smith", "age": 28}
]

我试图想象如何使用Swift中新的可编码特性将它们转换为类中的两个对象。因此,如果我有一个可编码的person类,我希望得到这个响应,并让它给我两个person对象。

我也在使用Alamofire来处理请求。

我该怎么做?到目前为止,我看到的所有与可编码的东西相关的东西只允许一个对象。我还没有看到与Alamofire或web框架的任何集成。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-08-29 00:25:10

有关阿拉莫火的最新情况5:responseJSONDecodable

代码语言:javascript
复制
struct Person: Codable {
    let firstName, lastName: String
    let age: Int

    enum CodingKeys : String, CodingKey {
        case firstName = "firstname"
        case lastName = "lastname"
        case age
    }
}

Alamofire.request(request).responseJSONDecodable { (response: DataResponse<Person>) in
    print(response)
}

Alamofire 4暂时不添加可编码的支持(请参阅#2177),您可以使用这个扩展:https://github.com/Otbivnoe/CodableAlamofire

代码语言:javascript
复制
let jsonData = """
[
    {"firstname": "Tom", "lastname": "Smith", "age": 31},
    {"firstname": "Bob", "lastname": "Smith", "age": 28}
]
""".data(using: .utf8)!

struct Person: Codable {
    let firstName, lastName: String
    let age: Int

    enum CodingKeys : String, CodingKey {
        case firstName = "firstname"
        case lastName = "lastname"
        case age
    }
}

let decoded = try! JSONDecoder().decode([Person].self, from: jsonData)

样本:http://swift.sandbox.bluemix.net/#/repl/59a4b4fad129044611590820

使用CodableAlamofire:

代码语言:javascript
复制
let decoder = JSONDecoder()
Alamofire.request(url).responseDecodableObject(keyPath: nil, decoder: decoder) { (response: DataResponse<[Person]>) in
    let persons = response.result.value
    print(persons)
}

keypath对应于JSON结构中包含结果的路径。例如:

代码语言:javascript
复制
{
    "result": {
        "persons": [
            {"firstname": "Tom", "lastname": "Smith", "age": 31},
            {"firstname": "Bob", "lastname": "Smith", "age": 28}
        ]
    }
}

keypath => results.persons

代码语言:javascript
复制
[
    {"firstname": "Tom", "lastname": "Smith", "age": 31},
    {"firstname": "Bob", "lastname": "Smith", "age": 28}
]

keypath => nil (空keypath抛出异常)

票数 19
EN

Stack Overflow用户

发布于 2017-11-18 06:14:41

我成功地序列化了可编码对象的数据响应。

例如,您可能已经熟悉了转换json对象[String: String]。这个json对象需要使用Data转换为json.data(using: .utf8)!

使用Alamofire,很容易获得数据(或者至少这种数据对我有用,已经与.utf8兼容了),我可以使用这个已经可用的函数。

代码语言:javascript
复制
func responseData(queue: DispatchQueue?, completionHandler: @escaping (DataResponse<Data>) -> Void) -> Self

然后,只需使用该数据作为DecodercompletionHandler中的输入。

代码语言:javascript
复制
let objek = try JSONDecoder().decode(T.self, from: data)

您还可以从文档中将其转换为一些泛型序列化函数,只需稍加调整即可。

泛型响应对象序列化

对此修改

代码语言:javascript
复制
func responseCodable<T: Codable>(
    queue: DispatchQueue? = nil,
    completionHandler: @escaping (DataResponse<T>) -> Void)
    -> Self
{
    let responseSerializer = DataResponseSerializer<T> { request, response, data, error in
        guard error == nil else { return .failure(BackendError.network(error: error!)) }

        guard let data = data else {
            return .failure(BackendError.objectSerialization(reason: "data is not valid"))
        }


        do{
            let objek = try JSONDecoder().decode(T.self, from: data!)
            return .success(objek)
        } catch let e {
            return .failure(BackendError.codableSerialization(error: e))
        }

    }

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

样本结构

代码语言:javascript
复制
struct Fids: Codable {

   var Status: Status?
   var Airport: Airport?
   var Record: [FidsRecord]
}

以这种方式使用这个函数

代码语言:javascript
复制
    Alamofire.request("http://whatever.com/zzz").responseCodable { (response: DataResponse<Fids>) in
        switch response.result{
        case .success(let value):
            print(value.Airport)
        // MARK: do whatever you want
        case .failure(let error):
            print(error)
            self.showToast(message: error.localizedDescription)
        }
    }
票数 0
EN

Stack Overflow用户

发布于 2019-10-16 14:10:23

要解码到数组,您可以使用类型别名进行响应,以获得清晰性:

typealias ServiceResponseObject = [ResponseObject]

但是,您必须确认Array是否可以编码:

extension Array: Decodable where Element: Decodable {}

这样才能让一切都正常。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45928894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档