2

I am trying to add json values in JSQMessageData to show the message on JSQMessagesViewController. The view is set up and this the lite chat(can chat only once).We use an api to send and receive messages. The problem is when I fetched data from api as json it returns the value. I want to append that json data to the rest of my JSQMessages objects, I tried the last few days and have failed to accomplish this. Here is the full code and json response.

    APIHandler.requestGETURL(urlString, success: { (JSON) in
        print(JSON)

        // var messageDictionary : [JSQMessageData] = []
        // this is the message object
        // i want to add the json data to my messageDictionary
        // reload collection view

        /*
         {
         "message_time" : "27-05-2017",
         "user_id" : 1924,
         "user_name" : "Tester name",
         "message" : "hi",
         "user_thumb" : "<image_path>"
         },
         {
         "message_time" : "27-05-2017",
         "user_id" : 1924,
         "user_name" : "Tester name",
         "message" : "how are you?",
         "user_thumb" : "<image_path>"
         }
         */

        // i want to 
      let arrayNames =  JSON["data"]
      self.messageDictionary.append(JSQMessageData()) 
      // I am stuck here
    }) { (Error) in
        print(Error.localizedDescription)
    }
Dan Leonard
  • 3,325
  • 1
  • 20
  • 32
Lije
  • 45
  • 1
  • 8

2 Answers2

0

If I understand you correctly you're trying to parse json into a JSQMessage object. Your message data is not overly complex, it contains all the things a standard JSQMessage needs. So there is not any reason to create your own JSQMessageData object. You can just use one of the JSQMessage initializers. Since you are only using "Text" messages and not any other "Media" the

JSQMessage(senderId: <String!>, senderDisplayName: <String!>, date: <#Date>, text: <String>)

should be all you need. So all you need to do is get the values out of your json response. There are many ways to do this.

I am going to assume that the json you provided is also wrapped in a list like this

[
  { "message_time" : "27-05-2017",
    "user_id" : 1924,
    "user_name" : "Tester name",
    "message" : "hi",
    "user_thumb" : "<image_path>"
  },
  { "message_time" : "27-05-2017",
    "user_id" : 1924,
    "user_name" : "Tester name",
    "message" : "how are you?",
    "user_thumb" : "<image_path>"
  } 
]

We can utilise the flatmap function to get our "Messages" out of the json data. You also do not need a dictionary becasue there is not key for each message so just use a list that contains JSQMessageObjects

var messages:[JSQMessages] = []
var imageDictionary: [userID: String: imagePath: String] = [:]

APIHandler.requestGETURL(urlString, success: { (JSON) in
  print(JSON)
  let messagesJSON = response.result.value as? [[String: Any]] ?? [[:]]
    guard let listOfMessages = JSON as? [[String: AnyObject]]
    messages: [JSQMessage] = listOfMessages.flatmap { messageData in
     guard let dateCreated = messageData["message_time"] as? Date,
       let userID = messageData["user_id"] as? String,
       let userName = messageData["user_name"] as? String,
       let text = messageData["message"] as? String  else {
          //If any of these things are missing we do not want to save the entry 
          return nil
     }

    let imagePath = messageData["user_thumb"] as? String

imageDictionary[userID] = imagePath return JSQMessage(senderId: userID, senderDisplayName: userName, date: dateCreated, text: text)

  }) { (let error: Error) in
     if error != nil {
        print(Error.localizedDescription)
     }
}

I would save your image paths into a dictionary and fetch them on a background thread that way users can view the messages while the images populate as they arrive. Then once they have loaded apply them to your messages. or you can add it to your own custom message object that conformes to the JSQMessageDataSource protocol. for more on how to accomplish that check out this post

Dan Leonard
  • 3,325
  • 1
  • 20
  • 32
0

@Daniel is saying right, your json is enough simple that you don't need to add any JSQMessageData and maybe you are actually doing some extra effort, i have faced similar kind of problem when i need to pass a NSDictionary object with JSQMessage Objects so i used a tricky way for doing that ( and it works perfectly fine :) )

not sure about your case but this helps me a lot in many situations so follow these steps :

  1. convert your json data into string
  2. now save this json string into the accessebilityHint property of JSQmessage object. like -

    (jsqmessageObj).accessibilityHint = jsonString

  3. as according to your need as you want to use this json just extract the JSQmessage Object (like in cellForRowAtIndexPath ! ) , just use (jsqmessageObj).accessibilityHint to get back your json string decode it and use it as your need.
    like - strJson = (jsqmessageObj).accessibilityHint

Hope this will help :p

iNoob
  • 144
  • 1
  • 15