Reputation: 1
I'm new to swift :D, and developing a simple chatting application using the JSQMessagesViewController. I read & followed JSQMessagesViewController sample project (https://www.syncano.io/blog/create-ios-chat-app-part1/) but my code occurs an error.
class ChatRoomViewController: JSQMessagesViewController {
let incomingBubble = JSQMessagesBubbleImageFactory().incomingMessagesBubbleImageWithColor(UIColor(red: 10/255, green: 180/255, blue: 230/255, alpha: 1.0))
let outgoingBubble = JSQMessagesBubbleImageFactory().outgoingMessagesBubbleImageWithColor(UIColor.lightGrayColor())
var messages = [JSQMessage]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.setup()
self.addDemoMessages()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func reloadMessagesView() {
self.collectionView?.reloadData()
}
func gotoReserve() {
let nextViewController = ReserveViewController(nibName: "ReserveViewController", bundle: nil)
self.navigationController!.pushViewController(nextViewController, animated: true)
}
}
//MARK - Setup
extension ChatRoomViewController {
func addDemoMessages() {
let message = JSQMessage(senderId: "zzz", displayName: "aaa", text: "asasd")
self.messages.append(message)
self.reloadMessagesView()
}
func setup() {
self.senderId = "user"
self.senderDisplayName = "user"
}
}
//MARK - Data Source
extension ChatRoomViewController {
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.messages.count
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
let data = self.messages[indexPath.row]
return data
}
override func collectionView(collectionView: JSQMessagesCollectionView!, didDeleteMessageAtIndexPath indexPath: NSIndexPath!) {
self.messages.removeAtIndex(indexPath.row)
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let data = messages[indexPath.row]
switch(data.senderId) {
case self.senderId:
return self.outgoingBubble
default:
return self.incomingBubble
}
}
override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
}
//MARK - Toolbar
extension ChatRoomViewController {
override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: NSDate!) {
let message = JSQMessage(senderId: senderId, senderDisplayName: senderDisplayName, date: date, text: text)
self.messages += [message]
self.finishSendingMessage()
}
override func didPressAccessoryButton(sender: UIButton!) {
}
}
When I run it, the error message say
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[JSQMessage messageHash]: unrecognized selector sent to instance 0x7fdf0a6e1f60'
and the app is terminated.
But it runs well after erasing
self.addDemoMessages()
code in viewDidLoad(). So I guess this code occurs error, but I don't know how to fix :( How can I fix it?
Upvotes: 0
Views: 111
Reputation: 4037
Here is my case,
to solve it by
Add -all_load
to the other linker flags in your build settings.
-all_load forces the linker to load all object files from every archive it sees, even those without Objective-C code.
and
-force_load is available in Xcode 3.2 and later. It allows finer grain control of archive loading.
Each -force_load option must be followed by a path to an archive, and every object file in that archive will be loaded.
Upvotes: 0
Reputation: 3405
I had a similar problem with this when I subclassed the JSQMessage
object. If you are doing that you just need to make sure that you implement the has for the message data. I just had to add this method to my message
object
func messageHash() -> UInt {
return UInt(self.hash)
}
Hope that helps 👻
Upvotes: 1