0

I'm trying to fetch some json data as follows:

[
    {
        "_id": "5ccbf88042b2f60ec690a8dd",
        "title": "Conference1",
        "description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.",
        "cities": [
            {
                "name": "Paris",
                "numberOfUsers": "3"
            },
            {
                "name": "Marseille",
                "numberOfUsers": "7"
            },
            {
                "name": "Lyon",
                "numberOfUsers": "2"
            }
        ]
    }

    {
        "_id": "5ccbf88042b2f60ec690a8dd",
        "title": "Conference1",
        "description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.",
        "cities": [
            {
                "name": "Paris",
                "numberOfUsers": "5"
            },
            {
                "name": "Marseille",
                "numberOfUsers": "10"
            },
            {
                "name": "Lyon",
                "numberOfUsers": "8"
            }
        ]
    }

]

Here is my code :

class Event: NSObject{

    var title: String? = ""
    var eventDescription: String? = ""
    var cities: [String:String]? = ["":""]
    var name: String? = ""
    var numberOfUsers: String? = ""


    static func parseEventData(data: Data) -> [Event] {
        var eventsArray = [Event]()

        do {
            let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)

            //Parse JSON Data
            if let events = jsonResult as? [Dictionary<String,AnyObject>] {
                for event in events {
                    let newEvent = Event()
                    newEvent.title = event["title"] as? String
                    newEvent.eventDescription = event["description"] as? String

                    newEvent.cities = event["cities"] as? [String:String]
                    for city in newEvent.cities? {
                        newEvent.name = city["name"] as? String
                        newEvent.numberOfUsers = city["numberOfUsers"] as? String
                    }



                    eventsArray.append(newEvent)
                }
            }

        }catch let err {
            print(err)
        }

        return eventsArray
    }
}

Code compiles well for title, and description but I'm stuck to catch cities correctly. Any help would be appreciated. Thank you

1
  • 3
    You should use Decodable, JSONDecoder, and proper structures. Commented Jun 3, 2019 at 15:30

1 Answer 1

1

Correct json ( you miss a comma between array elements , )

[{
    "_id": "5ccbf88042b2f60ec690a8dd",
    "title": "Conference1",
    "description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.",
    "cities": [{
            "name": "Paris",
            "numberOfUsers": "3"
        },
        {
            "name": "Marseille",
            "numberOfUsers": "7"
        },
        {
            "name": "Lyon",
            "numberOfUsers": "2"
        }
    ]
},
{
    "_id": "5ccbf88042b2f60ec690a8dd",
    "title": "Conference1",
    "description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.",
    "cities": [{
            "name": "Paris",
            "numberOfUsers": "5"
        },
        {
            "name": "Marseille",
            "numberOfUsers": "10"
        },
        {
            "name": "Lyon",
            "numberOfUsers": "8"
        }
    ]
}

]

`// MARK: - Element
struct Root: Codable {
    let id, title, purpleDescription: String
    let cities: [City]

    enum CodingKeys: String, CodingKey {
        case id = "_id"
        case title
        case purpleDescription = "description"
        case cities
    }
}

// MARK: - City
struct City: Codable {
    let name, numberOfUsers: String
}

let res = try! JSONDecoder().decode([Root].self,from:data)
print(res)

Edit : here this ( cities is an array )

 newEvent.cities = event["cities"] as? [String:String]

should be

 newEvent.cities = event["cities"] as? [[String:String]]

do {
    let jsonResult = try JSONSerialization.jsonObject(with: data, options:[])

    //Parse JSON Data
    if let events = jsonResult as? [[String:Any]] {
        for event in events {
            let newEvent = Event()
            newEvent.title = event["title"] as? String
            newEvent.eventDescription = event["description"] as? String

            newEvent.cities = event["cities"] as? [[String:String]]
            for city in newEvent.cities ?? [["no city found": "number of users : 0"]] {
                newEvent.name = city["name"] ?? ""
                newEvent.numberOfUsers = city["numberOfUsers"] ?? ""
            } 
            eventsArray.append(newEvent)
        }
    }

}catch  {
    print(error)
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your help, but could you suggest any code correctness with JSONSerialization please? I don't have much time to rebuild my project on Codable :)
it's better to do this whatever costs , but if you have try edit
also if you're 100% the value won't be nil directly use ! instead of optionals

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.