使用JSQMessagesViewController的NSInvalidArgumentException

时间:2016-04-02 07:57:06

标签: ios swift jsqmessagesviewcontroller

我是swift:D的新手,并使用JSQMessagesViewController开发一个简单的聊天应用程序。我读过&跟随JSQMessagesViewController示例项目(https://www.syncano.io/blog/create-ios-chat-app-part1/)但我的代码出错了。

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!) {

    }
}

当我跑的时候, 错误信息说

  

***由于未捕获的异常终止应用程序' NSInvalidArgumentException',原因:' - [JSQMessage messageHash]:无法识别的选择器发送到实例0x7fdf0a6e1f60'

并终止该应用程序。

但它在擦除后运行良好

  

self.addDemoMessages()

viewDidLoad()中的

代码。所以我猜这段代码发生错误,但我不知道如何修复:(我该如何解决?

2 个答案:

答案 0 :(得分:1)

当我将JSQMessage对象子类化时,我遇到了类似的问题。如果您这样做,您只需要确保为消息数据实现has。我只需将此方法添加到我的message对象

func messageHash() -> UInt {
    return UInt(self.hash)
}

希望有所帮助

答案 1 :(得分:0)

这是我的情况,

解决

public IEnumerable<DetalleSolicitud> GetDetallesPorUsuarioParaAsignacion(string userId) { return _context.DetalleSolicituds .Include(a => a.HistorialAsignacionAlistadors) .Include(s => s.Solicitudes.Pedido.ReservasProducs.Select(a => a.DetalleTalla.Producto)) .Where(a => a.AlistadorId == userId) .GroupBy(a => DbFunctions.TruncateTime((DateTime)a.FechaAsignacionAlistado)) .ToList().Select(x => new DetalleSolicitud { FechaAsignacionAlistado = x.Key }); } 添加到构建设置中的其他链接器标志。

-all_load强制链接器从它看到的每个存档中加载所有目标文件,即使是没有Objective-C代码的文件。

-force_load在Xcode 3.2和更高版本中可用。可以更精细地控制存档加载。

每个-force_load选项后面必须有一个归档文件的路径,并且该归档文件中的每个目标文件都会被加载。