Beomjin Ahn
Beomjin Ahn

Reputation: 1

NSInvalidArgumentException with using JSQMessagesViewController

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

Answers (2)

dengST30
dengST30

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

Dan Leonard
Dan Leonard

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

Related Questions