Goal:
When I select a message from the list of chat messages in the MessageListController
with didSelectRowAt
, I want the opened chat session in the next ChatDetailController
to match the same conversation that was selected. Obviously.
I'm working with WatchKit but it's the same thing in this iOS image. The message with Sophia is selected and the chat with Sophia opens.
I want to pass the json "message_id" i.e. the chatMessageId
property from my model. I'm already passing the chatMessageId
from the MessageModel
to the ChatDetailController
with this line presentController(withName: "ChatDetailController", context: messageContext)
Here is a print out of the passed data using messageContext
.
Passed context: Optional(HTWatch_Extension.MessageModel(partner: "9859", nickname: "Marco", message: "Have you seen is dog?", city: "Madrid", countryBadgeImageURL: https://i.sstatic.net/0Z3ZO.jpg, messageListImageURL: https://i.sstatic.net/0Z3ZO.jpg, chatMessageId: "Tva9d2OJyWHRC1AqEfKjclRwXnlRDQ", status: "offline"))
What's the next step? How do I tell the ChatDetailController
to populate its table with the conversation that matches the row that was selected?
MessageListController
// ...code...
let messageObject = [MessageModel]()
//var chatObject = [ChatModel]()
// ...code...
override func table(_ table: WKInterfaceTable, didSelectRowAt rowIndex: Int) {
var messageContext = messageObject[rowIndex]
var chatContext = chatObject[rowIndex]
do {
guard let fileUrl = Bundle.main.url(forResource: "Chats", withExtension: "json") else {
print("File could not be located")
return
}
let data = try Data(contentsOf: fileUrl)
let decoder = JSONDecoder()
let msg = try decoder.decode([ChatModel].self, from: data)
self.chatObject = msg
} catch let error {
print(error)
}
// I got part of this line from a previous question, but these property types do not match.
// No matter what chatObject I create I cannot access it/assign it.
// Also I do not want to mutate messageContext which Xcode is telling me to do.
messageContext.chatMessageId = (chatObject as AnyObject).filter { (dictionaryTemp:[String:String]) -> Bool in
return dictionaryTemp["message_id"] == chatContext.chatMessageId
}
// WatchKit's model presentation method.
presentController(withName: "ChatDetailController", context: messageContext)
}
ChatDetailController
var chats: [ChatModel] = []
var messageModel: MessageModel? {
didSet {
guard let model = messageModel else { return }
partnerLabel.setText(model.nickname)
}
}
override func awake(withContext context: Any?) {
super.awake(withContext: context)
if let message = context as? MessageModel {
self.messageModel = message
print("Passed context: \(String(describing: messageModel))")
} else {
print("Passed context error: \(String(describing: context))")
}
do {
guard let fileUrl = Bundle.main.url(forResource: "Chats", withExtension: "json") else {
print("File could not be located")
return
}
let data = try Data(contentsOf: fileUrl)
let decoder = JSONDecoder()
let msg = try decoder.decode([ChatModel].self, from: data)
self.chats = msg
} catch let error {
print(error)
}
DispatchQueue.main.async(execute: {
self.setupTable(chatMessageArray: self.chats as [AnyObject])
})
}
ChatModel
public struct ChatModel: Codable {
// ... other properties
public var chatMessageId: String
enum CodingKeys: String, CodingKey {
// ... other cases
case chatMessageId = "message_id"
}
init (message:String , fromId:String, toID : String, imgUrl : URL?, chatMessageId : String) {
// ... other properties
self.chatMessageId = chatMessageId
}
}
// .... decoders etc
}
MessageModel
public struct MessageModel: Codable {
// ...
public var chatMessageId: String
enum CodingKeys: String, CodingKey {
// ... other cases
case chatMessageId = "message_id"
}
// ... init/decoders etc
}
Messages.json
[
{
"userid": "4444",
"nickname": "Marco",
"online_status": "offline",
"message": "Have you seen his dog?",
"city": "Madrid",
"flag_url": "https://i.sstatic.net/0Z3ZO.jpg",
"creationDate": "2016-02-22 15:18:40",
"avatar_url": "https://i.sstatic.net/0Z3ZO.jpg",
"message_id": "Tva9d2OJyWHRC1AqEfKjclRwXnlRDQ" // different id
},
{
"userid": "12121",
"nickname": "Tom",
"online_status": "online",
"message": "Where is the pizza shop?",
"city": "Kyoto",
"flag_url": "https://i.sstatic.net/0Z3ZO.jpg",
"creationDate": "2016-02-22 15:18:40",
"avatar_url": "https://i.sstatic.net/0Z3ZO.jpg",
"message_id": "EnotMkk8REEd0DHGvUgnd45wBap80E" // different id
}
]
Chats.json
2 conversations containing 2 messages each. Each conversation has a unique fromId
(partner), toID
(myself), and unique message_id
.
[
{
"fromId": "zz1234skjksmsjdfwe2zz",
"toId": "qq43922sdkfjsfmmxdfqq",
"messageText": "Have you seen is dog?",
"imageUrl": "https://i.sstatic.net/0Z3ZO.jpg",
"message_id": "Tva9d2OJyWHRC1AqEfKjclRwXnlRDQ", // conversation 1 - same message id as the 1st message in Messages.josn with nickname Marco.
"read": "true"
},
{
"fromId": "zz1234skjksmsjdfwe2zz",
"toId": "qq43922sdkfjsfmmxdfqq",
"messageText": "Yes I have. It's cute.",
"imageUrl": "https://i.sstatic.net/0Z3ZO.jpg",
"message_id": "Tva9d2OJyWHRC1AqEfKjclRwXnlRDQ", // conversation 1
"read": "true"
},
{
"fromId": "bb888skjaaasjdfwe2333",
"toId": "qq43922sdkfjsfmmxdfqq",
"messageText": "What kind of pizza do you want?",
"imageUrl": "https://i.sstatic.net/0Z3ZO.jpg",
"message_id": "EnotMkk8REEd0DHGvUgnd45wBap80E", // conversation 2 - same message id as the 2nd message in Messages.josn with nickname Tom.
"read": "true"
},
{
"fromId": "bb888skjaaasjdfwe2333",
"toId": "qq43922sdkfjsfmmxdfqq",
"messageText": "I like ham & pineapple pizza.",
"imageUrl": "https://i.sstatic.net/0Z3ZO.jpg",
"message_id": "EnotMkk8REEd0DHGvUgnd45wBap80E", // conversation 2
"read": "true"
}
]
let msg = try decoder.decode([ChatModel].self, from: data)
self.chats = msg
You are storing all chat data contained in Chats.json
into chats
property.
To filter chats, try replacing second line like below
self.chats = msg.filter { chat in
return chat.chatMessageId == self.messageModel.chatMessageId
}
or, while I don't know why all chats are contained in single json file, it will be better to separate json file into multiple files for each chat like Chat-Tva9d2OJyWHRC1AqEfKjclRwXnlRDQ.json
.
I hope this will help.