Reputation: 2009
How do I create a data model with SwiftyJSON and a 2nd set of nested array of objects? I'm able to parse and store the top level objects fine, but not the inner ones. noteimages in particular, I can't seem to figure out. Below is the api results and under that is how I am trying to do it, although not quite right.
[
{
"id": 1,
"title": "some title",
"details": "here are some details",
"userId": 1,
"hidden": false,
"createdAt": "2018-02-14T07:02:33.000Z",
"updatedAt": "2018-02-14T07:02:33.000Z",
"contactId": 1,
"noteimages": [
{
"id": 2,
"imageUrl": "someimage222.jpg",
"userId": 1,
"hidden": false,
"createdAt": "2018-02-14T07:02:58.000Z",
"updatedAt": "2018-02-15T04:41:05.000Z",
"noteId": 1
}
]
}
]
Alamofire.request(url, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: header).responseJSON { (response) in
if response.result.error == nil {
guard let data = response.data else { return }
do {
if let json = try JSON(data: data).array {
print(json)
for item in json {
let title = item["title"].stringValue
let details = item["details"].stringValue
var noteImages: [Dictionary<String, AnyObject>]
for image in item["noteimages"].arrayValue {
noteImages.append(image["imageUrl"])
}
let note = Note(title: title, details: details, noteImage: noteImages)
self.notes.append(note)
}
//print(response)
completion(true)
}
} catch {
debugPrint(error)
}
} else {
completion(false)
debugPrint(response.result.error as Any)
}
}
Upvotes: 2
Views: 1776
Reputation: 20804
Your issue is that you are getting the value string in key imageUrl
and you are adding as dictionary so if you need an array of dictionary you need to add those values in item["noteimages"].arrayValue
directly or if you need an array of imageUrl
you need to change the type of noteImages
var to String
type
var noteImages: [Dictionary<String, AnyObject>]// this should be [String:AnyObject]] swifty way
for image in item["noteimages"].arrayValue {
noteImages.append(image["imageUrl"]) //this is an String not an Dictionary
}
To fix this you need one of three options
Option 1: Use an array of dictionary
var noteImages: [[String:AnyObject]] = []
for image in item["noteimages"].arrayValue {
if let imageDict = image as? [String:AnyObject]{
noteImages.append(imageDict) //adding in a dictionary array
}
}
Option 2: Use an array of String
var noteImages: [String] = []
for image in item["noteimages"].arrayValue {
if let imageDict = image as? [String:AnyObject]{
noteImages.append(imageDict["imageUrl"])
}
}
Option 3: convert your dictionary to a Model object
var noteImages: [YourModelName] = []
for image in item["noteimages"].arrayValue {
if let imageDict = image as? [String:AnyObject]{
noteImages.append(YourModelName(dictionary:imageDict)) //adding in a model object created from a dictionary
}
}
Upvotes: 3
Reputation: 2009
This is what I ended up doing:
var notes = [Note]()
var noteImages = [NoteImage]()
....
Alamofire.request(url, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: header).responseJSON { (response) in
if response.result.error == nil {
guard let data = response.data else { return }
do {
if let json = try JSON(data: data).array {
print(json)
for item in json {
let title = item["title"].stringValue
let details = item["details"].stringValue
//loop through nested array
for innerItem in item["noteimages"].arrayValue {
let noteImage = NoteImage(imageUrl: innerItem["imageUrl"].stringValue)
self.noteImages.append(noteImage)
}
print("note images: \(self.noteImages)")
let note = Note(title: title, details: details, noteImage: self.noteImages)
self.notes.append(note)
}
//print(response)
completion(true)
}
} catch {
debugPrint(error)
}
} else {
completion(false)
debugPrint(response.result.error as Any)
}
}
Upvotes: 0