Well I’m working on a ChatViewController, My UI is freeze when a receive a message via socket and try to reload the data (before reload, I add the message to an array and adapt the array to an array of dictionary to apply the section - separate the rows by date).
Example Code (Excerpt):
SocketManager: (Here, I have a listener to message that I receive as a Dictionary, and well I create a message object and send to the delegate)
socket!.on("message") { (data:[AnyObject], emitter:SocketAckEmitter) -> Void in
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
if let messageDict = data.first as? NSDictionary{
var accountId = 0
if let accountIdTmp = messageDict.objectForKey("accountId") as? Int{
accountId = accountIdTmp
}
var firstName = ""
if let firstNameTmp = messageDict.objectForKey("firstName") as? String{
firstName = firstNameTmp
}
var lastName = ""
if let lastNameTmp = messageDict.objectForKey("lastName") as? String{
lastName = lastNameTmp
}
var tableId = 0
if let tableIdTmp = messageDict.objectForKey("tableId") as? Int{
tableId = tableIdTmp
}
var body = ""
if let bodyTmp = messageDict.objectForKey("body") as? String{
body = bodyTmp
}
let account = Account(identifier: "\(accountId)", name: firstName, lastName: lastName)
let message = Message(identifier: 0, created: NSDate(), tableId: tableId, body: body, accountId: accountId, account: account)
self.chatDelegate?.recievedMessage(message)
}
})
}
MessageAdapter: (Here, I only show the method adaptMessageToTime, based on an array of Messages convert to an array of dictionary)
Example
Input: [MessageObject1,MessageObject2,MessageObject3]
Ouput: [[“date”:“10/03/2016”,“messages”:[MessageObject1,MessageObject2]],[“date”:“Today”,“messages”:[MessageObject3]]]
func adaptMessageToTime()->[[String:AnyObject]]{
let formatter = NSDateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
var containerMessages: [[String:AnyObject]] = []
for message in messages{
let key = Util.isDateInTodayRange(message.created) ? "Today" : formatter.stringFromDate(message.created)
var hasKey = false
for var (index, containerMessage) in containerMessages.enumerate(){
if containerMessage["date"] as? String == key{
hasKey = true
if var messageList = containerMessage["messages"] as? [Message]{
messageList.append(message)
containerMessage["messages"] = messageList
containerMessages[index] = containerMessage
}
}
}
if !hasKey{
containerMessages.append(["date":key,"messages":[message]])
}
}
return containerMessages
}
ChatViewController (Extension ChatDelegate): (Here, I show the delegate that receive the message, and that’s where a think is degrading the performance and freeze the UI, But I’m calling from the main thread the part of update, also I put the adaptMessageToTime method in a BackgroundQueue because that part is a consuming task, ex. It can be 100000 messages and I’m recreating the array of dictionary).
extension ChatViewController : ChatDelegate{
func recievedMessage(message: Message) {
if let tableMessage = self.tableMessage where tableMessage.identifier == message.tableId{
let backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
dispatch_async(backgroundQueue, { () -> Void in
self.messageAdapter?.addMessage(message)
if let messsagesByTimeTmp = self.messageAdapter?.adaptMessageToTime(){
self.messagesByTime = messsagesByTimeTmp
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tblMessages.reloadData()
self.scrollToBottom()
})
}
})
}
}
}