JSQMessageViewController:致命错误:索引超出范围

时间:2021-09-02 16:04:12

I am using JSQMessageViewController for chat implementation. i am able to send and receive messages through json Post and get.

我正在使用JSQMessageViewController进行聊天实现。我能够通过json Post发送和接收消息并获取。

i am able to load my chat history without any error. used timer(5 sec) for retrieving the messages.

我可以加载我的聊天记录而不会出现任何错误。使用计时器(5秒)来检索消息。

It works fine for some time,, it reloads the messages for each 5 sec.

它工作正常一段时间,它每5秒重新加载一次消息。

after a while i am getting "fatal error: Index out of range" suddenly on below line.

过了一会儿,我突然发现“致命错误:指数超出范围”。

override func collectionView(_ collectionView: JSQMessagesCollectionView, messageDataForItemAt indexPath: IndexPath) -> JSQMessageData {

     //app Crashes here : fatal error: Index out of range  
         return messages[indexPath.item]


}

BELOW IS CODE var messages = JSQMessage

以下是CODE var messages = JSQMessage

var outgoingBubbleImageView:JSQMessagesBubbleImage! //= JSQMessagesBubbleImageFactory().outgoingMessagesBubbleImage(with: UIColor.jsq_messageBubbleGreen())
var incomingBubbleImageView:JSQMessagesBubbleImage! //= JSQMessagesBubbleImageFactory().incomingMessagesBubbleImage(with: UIColor.jsq_messageBubbleLightGray())


 var batchMessages = true

// Refresh Messages
var timer : Timer!

// Don't double load!
var isLoading = false

override func viewDidLoad() {
    super.viewDidLoad()

    collectionView!.collectionViewLayout.incomingAvatarViewSize = CGSize.zero
    collectionView!.collectionViewLayout.outgoingAvatarViewSize = CGSize.zero

    outgoingBubbleImageView = JSQMessagesBubbleImageFactory().outgoingMessagesBubbleImage(with: uicolorFromHex(0xDCF8C7))
    incomingBubbleImageView = JSQMessagesBubbleImageFactory().incomingMessagesBubbleImage(with: UIColor.jsq_messageBubbleLightGray()) //uicolorFromHex(0xF6F6F6)


    let defaults = UserDefaults.standard
    let usertype = defaults.object(forKey: "UserType") as! String

    self.userType = usertype

// self.getChatHistory(ipAddress+"/VIOService.svc/JSONService/chatorderhistoryget/"+EmailId+"/"+toEmail+"/"+OrderId) // self.finishReceivingMessage()

// self.getChatHistory(ipAddress +“/ VIOService.svc / JSONService / chatorderhistoryget /”+ EmailId +“/”+ toEmail +“/”+ OrderId)// self.finishReceivingMessage()

    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Close", style: .plain, target: self, action: #selector(addTapped))
    self.sender = userType

    self.inputToolbar.contentView?.leftBarButtonItem = nil


    // This is a beta feature that mostly works but to make things more stable it is diabled.
    collectionView?.collectionViewLayout.springinessEnabled = false

    automaticallyScrollsToMostRecentMessage = true

   // self.collectionView?.reloadData()
   self.collectionView?.layoutIfNeeded()




   self.isLoading = false

  self.loadMessages()


}


override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    collectionView!.collectionViewLayout.springinessEnabled = false


 timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(ChatMessagesViewController.loadMessages), userInfo: nil, repeats: true)


}

func addMessage(_ id: String, text: String) {
    print("add message: \(text)")



    let message = JSQMessage(senderId: id, displayName: "Me", text: text)


    messages.append(message)



}

func loadMessages() {

// self.messages = [JSQMessage]()

  //  self.messages.removeAll()

  if self.isLoading == false {

        isLoading = true

        self.getChatHistory(mYURL)


        finishReceivingMessage()


    }

}

func getChatHistory(_ url:String) {

func getChatHistory(_ url:String){

messages.removeAll()
  //  messages.removeAll(keepingCapacity: true)

    let requestURL: URL = URL(string: url)!
    let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: requestURL)
    let session = URLSession.shared
    let task = session.dataTask(with: urlRequest as URLRequest) {data,response,error in

        let httpResponse = response as! HTTPURLResponse
        let statusCode = httpResponse.statusCode

        if (statusCode == 200) {
            print("everything is fine, file downloaded successfully.")

            print(response!)


            do{



                let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments)

                if let items = json as? [[String: AnyObject]] {



                    for item in items {

                        if let sentBy = item["SentBy"] as? String {

                            if let SentTo = item["SentTo"] as? String {

                                if let Message = item["Msg"] as? String {

                                    if let IsType = item["IsType"] as? String  {

                                        if let mesSentOn = item["MsgSenton"] as? String //Date {

                                        {

//
let add = chatHistory(SentBy: sentBy, SentTo: SentTo, Message: Message, IsType: IsType, SentOn: mesSentOn)

// let add = chatHistory(SentBy:sentBy,SentTo:SentTo,Message:Message,IsType:IsType,SentOn:mesSentOn)

                                            self.chatHist.append(add)

                                            self.from = SentTo
                                            self.to = sentBy

                                            var message:String=""

                                            if let range = Message.range(of: ";") {

                                             message = Message.substring(from: range.upperBound)
                                            }

                                           self.addMessage(IsType, text: message)


                                        }
                                    }
                                }
                            }

                        }

                     self.do_collectionView_refresh()

                    }



                }



            }
            catch {

                print("Error with Json: \(error)")
            }

        }
    }


    isLoading = false

    task.resume()



}

func do_collectionView_refresh() {

func do_collectionView_refresh(){

    DispatchQueue.main.async {

        self.collectionView?.reloadData()

    }
}


override func senderId() -> String {
    return userType
}

override func senderDisplayName() -> String {
    return "Me"
}

override func collectionView(_ collectionView: UICollectionView,
                             numberOfItemsInSection section: Int) -> Int {

    if messages.count > 0 {

        return messages.count
    }
    else {

        return 0
    }


  //  return messages.count
}


override func collectionView(_ collectionView: JSQMessagesCollectionView, messageDataForItemAt indexPath: IndexPath) -> JSQMessageData {

     //app Crashes here : fatal error: Index out of range  
         return messages[indexPath.item]


}


override func collectionView(_ collectionView: JSQMessagesCollectionView, messageBubbleImageDataForItemAt indexPath: IndexPath) -> JSQMessageBubbleImageDataSource {

//    return messages[indexPath.item].senderId == self.senderId() ? outgoingBubble : incomingBubble

    let message = messages[indexPath.item]

    //   let message = chatHist[indexPath.item]
    // 1
    if message.senderId == userType { //

        return outgoingBubbleImageView
    } else { // 3
        return incomingBubbleImageView
    }

}

i am stuck with the error, please someone help.

我遇到了错误,请有人帮忙。

1 个解决方案

#1


0  

Let me know if this makes a difference:

如果这有所不同,请告诉我:

 override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return messages.count

}

override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageDataForItemAt indexPath: IndexPath!) -> JSQMessageData! {

    let data = self.messages[indexPath.row]
    return data

}

 override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAt indexPath: IndexPath!) -> JSQMessageBubbleImageDataSource! {

    let data = messages[indexPath.row]
    switch(data.senderId) {
    case self.senderId:
        return self.outgoingBubbleImageView
    default:
        return self.incomingBubbleImageView
    }
}

#1


0  

Let me know if this makes a difference:

如果这有所不同,请告诉我:

 override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return messages.count

}

override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageDataForItemAt indexPath: IndexPath!) -> JSQMessageData! {

    let data = self.messages[indexPath.row]
    return data

}

 override func collectionView(_ collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAt indexPath: IndexPath!) -> JSQMessageBubbleImageDataSource! {

    let data = messages[indexPath.row]
    switch(data.senderId) {
    case self.senderId:
        return self.outgoingBubbleImageView
    default:
        return self.incomingBubbleImageView
    }
}