1

My php script sends a JSON response to my swift iOS app in the format shown below. This is parsed as an NSArray using the following code :

let jsonArray = try NSJSONSerialization.JSONObjectWithData(data_fixed!, options:[])

I have created the following objects in my swift code:

class Friend : NSObject {
var name: String?
var id: String?
var profile_pic : String?


}


class Message : NSObject {
var id: String?
var text: String?
var date: NSDate?
var sender: Friend?
}

class Chat : NSObject {
var id : String?
var chat_partner : Friend?
var chat_messages : [Message]?
}

What I want to do now is to loop through the NSArray below, and extract the data into instances of my objects, so in simple terms with the example below, I want to create two chat objects with id's 1 and 2, and all the appropriate variables. I am not sure how to execute such a loop properly in swift.

JSON Response:

Array: (
    {
    chatId = 1;
    message =         {
        1 =             {
            chatId = 1;
            "message_id" = 24242241;
            sender = 1233;
            text = "hello i am";
            timestamp = "2016-05-24 17:13:08";
        };
        2 =             {
            chatId = 1;
            "message_id" = 421421;
            sender = 1233;
            text = great;
            timestamp = "2016-05-24 17:15:08";
        };
    };
    "user1_id" = 1233;
    "user1_name" = David;
    "user1_profile_pic" = "http://graph.facebsddsaadsadsook.com/1233/picture?type=large";
    "user2_id" = 8543211123;
    "user2_name" = 0;
    "user2_profile_pic" = "<null>";
},
    {
    chatId = 2;
    "user1_id" = 23413524635;
    "user1_name" = 0;
    "user1_profile_pic" = "<null>";
    "user2_id" = 1233;
    "user2_name" = David;
    "user2_profile_pic" = "http://graph.facebsdadsook.com/1233/picture?type=large";
}
)

UPDATE : CODE ATTEMPT

                        var count_chats = 0;
                       for anItem in jsonArray as! [Dictionary<String, AnyObject>] {
                            let curr_chat = Chat()
                            if let chatId = anItem["chatId"] as? String {
                                curr_chat.id = chatId
                            }
                            let friend = Friend()
                            let user1id = anItem["user1_id"] as! String
                            let user2id = anItem["user2_id"] as! String
                            if (user1id == userID) {
                                if let user2id = anItem["user2_id"] as? String {
                                    friend.id = user2id
                                }
                                if let user2name = anItem["user2_name"] as? String {
                                    friend.name = user2name
                                }
                                if let user2profilepic = anItem["user2_profile_pic"] as? String {
                                    friend.profile_pic = user2profilepic
                                }
                            }
                            else if (user2id == userID){
                                if let user1id = anItem["user1_id"] as? String {
                                    friend.id = user1id
                                }
                                if let user1name = anItem["user1_name"] as? String {
                                    friend.name = user1name
                                }
                                if let user1profilepic = anItem["user1_profile_pic"] as? String {
                                    friend.profile_pic = user1profilepic
                                }
                        }
                            print("passed")
                                curr_chat.chat_partner = friend


                            var chat_messages : [Message]? = nil
                            var count_messages = 0;
                            if let dataArray = anItem["message"] as? NSArray {
                                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
                                }
                            }

                            curr_chat.chat_messages = chat_messages
                            self.user_chats![count_chats] = curr_chat
                            count_chats = count_chats + 1
Alk
  • 5,215
  • 8
  • 47
  • 116
  • 3
    So take a stab at it. Your data from JSON is going to come in as type `AnyObject`. You'll want to cast that to type [NSDictionary]. Then you'll need to fetch the key/value pairs from each dictionary entry, cast their values to the appropriate types, and build up your array of custom objects. If you get stuck post your code here and we'll help you debug it, but we're not going to write your code for you. – Duncan C May 25 '16 at 18:21
  • @DuncanC I have updated my question with the code attempt, could you please have a look and let me know if my approach is correct – Alk May 25 '16 at 18:50
  • No, that's not how this works. You put that code into Xcode, see if it compiles, and then debug it. If you can't get it working correctly, post back with the code as far as you got and we'll help you get unstuck, but I'm not going to proofread a bunch of code on a forum – Duncan C May 25 '16 at 19:01

2 Answers2

1

Not an answer but this might help you, you should maybe check that your property is not nil when you are writing things like this : curr_message.id = onemessage["chatId"] as! String . What you can do :

if let chatId = onemessage["chatId"] as? String {
   curr_message.id = chatId
}

Or if you want it to be more simple you can use Swifty JSON and write stuff like this :

curr_message.id = onemessage["chatId"].stringValue

Hope this can help you !

Chajmz
  • 729
  • 5
  • 11
  • Just a note: SwiftyJSON's `onemessage["chatId"].stringValue` is the same as Swift's `onemessage["chatId"] as! String`. If you want the safety of Optionals with SwiftyJSON, you still have to use `if let` but with `onemessage["chatId"].string` instead of Swift's `onemessage["chatId"] as? String`. – Eric Aya May 25 '16 at 19:16
  • @EricD I debugged through the code and applied the if let suggestions you guys had, everything works fine up to the line `if let dataArray = anItem["message"] as? NSArray {` where the if statement fails, and the program jumps straight to `curr_chat.chat_messages = chat_messages`, I'm not sure why this is – Alk May 25 '16 at 19:53
  • Have you tried to cast it as NSDictionary instead ? – Chajmz May 25 '16 at 20:05
0

I really don't know if this is going to actually help someone, but I have been blocked by this for 3 days. I finially saw this question, and literally the question was the answer for me, thanks for that @Alk. To make it short, I was dealing with this type of data (NSArray):

[<__NSArrayM 0x6000000556e0>(
{
    author = Julioenred;
    id = 1;
    text = "hello world";
},
{
    author = Pepe;
    text = "Saludos!!";
}
)
]

The data i needed was the author and text of each index, so I was able to do this:

for i in data.first as! [Dictionary<String, AnyObject>] {
    let message = Message(message: "", user: "")
    if let author = i["author"] as? String {
       message.author = author
    }
    if let text = i["text"] as? String {
       message.text = text
    }
 }

Basically i search in the dictionary for the keys I'm looking for, if anybody ask, this is the object Message:

import Foundation

class Message: Mappable {
    var author: String? = ""
    var text: String? = ""
    
    init(message: String, user: String) {
        self.author = user
        self.text = message
    }
}
jradich1234
  • 1,410
  • 5
  • 24
  • 29
Alessandro Pace
  • 206
  • 4
  • 8