So I have an API route that returns a JSON array of objects. For example:
[
{"firstname": "Tom", "lastname": "Smith", "age": 31},
{"firstname": "Bob", "lastname": "Smith", "age": 28}
]
I'm trying to envision how to use the new codable feature in Swift for to convert those into two objects in a class. So if I have a person class that is codable I would want to take that response and have it give me two person objects.
I'm also using Alamofire to handle the requests.
How can I do this? So far everything I've seen related to the codable stuff only allows 1 object. And I haven't seen any integration with Alamofire or a web framework.
Update regarding Alamofire 5: responseJSONDecodable
.
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 won't add Codable support for now (see #2177), you can use this extension instead: https://github.com/Otbivnoe/CodableAlamofire.
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)
Sample: http://swift.sandbox.bluemix.net/#/repl/59a4b4fad129044611590820
Using CodableAlamofire:
let decoder = JSONDecoder()
Alamofire.request(url).responseDecodableObject(keyPath: nil, decoder: decoder) { (response: DataResponse<[Person]>) in
let persons = response.result.value
print(persons)
}
keypath
corresponds to the path where the results are contained in the JSON structure. E.g:
{
"result": {
"persons": [
{"firstname": "Tom", "lastname": "Smith", "age": 31},
{"firstname": "Bob", "lastname": "Smith", "age": 28}
]
}
}
keypath
=> results.persons
[
{"firstname": "Tom", "lastname": "Smith", "age": 31},
{"firstname": "Bob", "lastname": "Smith", "age": 28}
]
keypath
=> nil
(empty keypath
throws an exception)
Very detailed answer. Thank you very much. Don't quite have time to look through it all now but will get to it at some point. Thanks so much!!!
Answer updated with Alamofire 5 code (no need for extensions)