Search code examples
jsonswiftnsarray

Parsing JSON response in Swift/iOS


I have the following JSON.

[{"chatId":"1","user1_id":"1212","user2_id":"8543211123","user1_name":"dave","user2_name":"daveee","user1_profile_pic":"http:\/\/graph.facebook.com\/1212\/picture?type=large","user2_profile_pic":"https:\/\/scontent-waw1-1.xx.fbcdn.net\/v\/t1.0-9\/1212.jpg?oh=c288ac7b31a61aee751e8ddafb05e78a&oe=57DC702E","message":{"1":{"message_id":"24242241","sender":"1212","chatId":"1","text":"hello i am","timestamp":"2016-05-24 17:13:08"},"2":{"message_id":"421421","sender":"1212","chatId":"1","text":"great","timestamp":"2016-05-24 17:15:08"}}},{"chatId":"2","user1_id":"23413524635","user2_id":"1212","user1_name":"Leo","user2_name":"dave","user1_profile_pic":"https:\/\/scontent-fra3-1.xx.fbcdn.net\/v\/l\/t1.0-1\/1212.jpg?oh=1212&oe=579AE3AE","user2_profile_pic":"http:\/\/graph.facebook.com\/1212\/picture?type=large","message":{"1":{"message_id":"21321213","sender":"1212","chatId":"2","text":"yes, hi","timestamp":"2016-05-25 15:46:57"}}}]

I want to loop through the message and for each counter, extract the values. This is my code:

for anItem in jsonArray as! [Dictionary<String, AnyObject>]
var chat_messages : [Message]? = nil
var count_messages = 0;
if let dataArray = anItem["message"] as? [Int : Dictionary<String, AnyObject> ] {
    for onemessage in dataArray as! [Dictionary<String, AnyObject>] {
        let curr_message = Message()
        if let messageid = onemessage["message_id"] as? String {
            curr_message.id =  messageid
        }
        if let messagedate = onemessage["timestamp"] as? NSDate {
            curr_message.date = messagedate
        }
        if let messagesender = onemessage["sender"] as? String {
            curr_message.sender = messagesender
        }
        if let messagetext = onemessage["text"] as? String {
            curr_message.text = messagetext
        }
        chat_messages![count_messages] = curr_message
        count_messages = count_messages + 1
    }
}

The problem is that the line if let dataArray = anItem["message"] as? [Int : Dictionary<String, AnyObject> ] { always fails and the if condition is never entered.


Solution

  • If you are using NSJSONSerialization, then every dictionary is of the type: [String : AnyObject]. So this line:

    if let dataArray = anItem["message"] as? [Int : Dictionary<String, AnyObject> ] {
    

    should be:

    if let dataArray = anItem["message"] as? [String : AnyObject] {
    

    And to loop through the message dictionaries inside dataArray you could replace:

    for onemessage in dataArray as! [Dictionary<String, AnyObject>] {
    

    with:

    for (_, messageDictionary) in dataArray {
        if let onemessage = messageDictionary as? [String : AnyObject] {
    

    and the rest of your code to get the various values out of the onemessage dictionary should work as you have it written now, except that this line will crash:

    chat_messages![count_messages] = curr_message
    

    Because you are forced unwrapping chat_messages, which you initialized as nil:

    var chat_messages : [Message]? = nil
    

    instead of as an empty array:

    var chat_messages = [Message]()