I'm writing in Swift 4, using viper structure and ObjectMapper to map my JSON response to my models.
I'm trying to map this rather complex JSON response with dynamic keys and am hoping to get some feedback on what I'm doing wrong.
Document is uploaded in whole month is return with month name as key and its all document list with value. My response is like this json:
{
"results": {
"2019-08": [
{
"id": 2,
"user_id": 7,
"document": "1566282328atlassian-git-cheatsheet1.pdf",
"name": "atoz",
"order": 0,
"is_edit": 0,
"edit_json": "",
"created_at": "2019-08-20 06:25:28",
"updated_at": "2019-08-20 06:25:28",
"date": "2019-08",
"url": "http://35.154.206.145/storage/pdf/1566282328atlassian-git-cheatsheet1.pdf"
},
{ ….}
],
"2019-07": [
{
"id": 2,
"user_id": 7,
"document": "1566282328atlassian-git-cheatsheet1.pdf",
"name": "atoz",
"order": 0,
"is_edit": 0,
"edit_json": "",
"created_at": "2019-08-20 06:25:28",
"updated_at": "2019-08-20 06:25:28",
"date": "2019-08",
"url": "http://35.154.206.145/storage/pdf/1566282328atlassian-git-cheatsheet1.pdf"
},
{ ….}
]
}
}
My model class is like this to fetch data in mapper model class
import ObjectMapper
struct GroupResponse: Mappable {
init?(map: Map) {}
var results: [String: DocumentObject]?
mutating func mapping(map: Map) {
results <- map["results"]
}
}
class DocumentObject: Mappable{
internal var months: [String: [DocumentListObject]]?
required init?(map: Map) {}
func mapping(map: Map) {
for (monthKey, monthValue) in map.JSON as! [String: [String: Any]] {
let month = DocumentListObject()
months?[monthKey] = [month]
}
}
}
class DocumentListObject {
var id:Int?
var user_id:Int?
var document:String?
var name:String?
var order:Int?
var is_edit:Bool?
var edit_json:String?
var date:String?
var url:String?
}
what is wrong in this, I get nil and crash when fatch this in api response
if let json = data as AnyObject? {
let arrayResponse = json as! NSDictionary
let arrayObject = Mapper<GroupResponse>().mapDictionary(JSON: arrayResponse as! [String : [String : Any]]) // I got crash here
print(arrayObject)
No need for DocumentObject
. try this,
struct GroupResponse: Mappable {
init?(map: Map) {}
var results: [String: [DocumentListObject]]?
mutating func mapping(map: Map) {
results <- map["results"]
}
}
Also, you forget to make DocumentListObject
conforming to Mappable
. Please update it as below,
class DocumentListObject: Mappable {
var id:Int?
var user_id:Int?
var document:String?
var name:String?
var order:Int?
var is_edit:Bool?
var edit_json:String?
var date:String?
var url:String?
required init?(map: Map) {}
func mapping(map: Map) {
id <- map["id"]
user_id <- map["user_id"]
document <- map["document"]
name <- map["name"]
order <- map["order"]
is_edit <- map["is_edit"]
edit_json <- map["edit_json"]
date <- map["date"]
url <- map["url"]
}
}
Usage:
let data = """
{
"results": {
"2019-08": [
{
"id": 2,
"user_id": 7,
"document": "1566282328atlassian-git-cheatsheet1.pdf",
"name": "atoz",
"order": 0,
"is_edit": 0,
"edit_json": "",
"created_at": "2019-08-20 06:25:28",
"updated_at": "2019-08-20 06:25:28",
"date": "2019-08"
}
]
}
}
"""
if let r = GroupResponse.init(JSONString: data), let result = r.results {
for (key, value) in result {
print("Key: \(key)" )
print("DocumentName: \(value.first!.document!)")
}
}
// prints
Key: 2019-08
DocumentName: 1566282328atlassian-git-cheatsheet1.pdf
When you have JSON
from the response, use below example to parse the GroupResponse.
let json = your JSON (of type [String: Any]) object retrieved from the API
if let r = GroupResponse.init(JSON: json), let result = r.results {
for (key, value) in result {
print("Key: \(key)" )
print("DocumentName: \(value.first!.document!)")
}
}