Поток 1: EXC_BAD_INSTRUCTION при попытке написать сообщение JSQMessagesViewController
Смотрите эту картинку для ошибки
Когда я пытаюсь написать сообщение, происходит сбой. Я не могу найти ошибку здесь. я получаю Thread 1: EXC_BAD_INSTRUCTION (code=EXC)_1386_INVOP, subcode=0x0.
Я пытаюсь найти в чем проблема в моей строке. Извините я просто новичок на xcode
Полный код ниже
import UIKit
import JSQMessagesViewController
import MobileCoreServices
import AVKit
import FirebaseDatabase
class ChatViewController: JSQMessagesViewController {
var messages = [JSQMessage]()
var messageRef = FIRDatabase.database().reference().child("messages")
override func viewDidLoad() {
super.viewDidLoad()
self.senderId = "1"
self.senderDisplayName = "Ej"
//messageRef.childByAutoId().setValue("first message")
//messageRef.childByAutoId().setValue("2nd")
// messageRef.observeEventType(FIRDataEventType.Value) { (snapshot: FIRDataSnapshot) in
// if let dick = snapshot.value as? NSDictionary {
// print(dick)
// }
// }
observeMessages()
}
func observeMessages(){
messageRef.observeEventType(.ChildAdded, withBlock: { snapshot in
//print(snapshot.value)
if let dick = snapshot.value as? [String: AnyObject]{
//let Mediatype = dick["Mediatype"] as! String
let senderId = dick["senderId"] as! String
let senderName = dick["senderName"] as! String
let text = dick["text"] as! String
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, text: text))
self.collectionView.reloadData()
}
})
}
//Send Btn
override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: NSDate!) {
//Messages
//messages.append(JSQMessage(senderId: senderId, displayName: senderDisplayName, text: text))
//self.collectionView.reloadData()
// print(messages)
let newMessage = messageRef.childByAutoId()
let messageData = ["text": text, "senderId": senderId, "senderName": senderDisplayName, "Mediatype": "TEXT"]
newMessage.setValue(messageData)
}
//File btn
override func didPressAccessoryButton(sender: UIButton!) {
// ALERT WHEN PRESSED ACCESSORY
let sheet = UIAlertController(title: "Media Messages", message: "Select A Media", preferredStyle: UIAlertControllerStyle.ActionSheet)
let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) { (alert:UIAlertAction) in
}
let photoLibrary = UIAlertAction(title: "Photo Library", style: UIAlertActionStyle.Default) { (alert: UIAlertAction) in
self.getMediaFrom(kUTTypeImage)
}
let videoLibrary = UIAlertAction(title: "Video Library", style: UIAlertActionStyle.Default) { (alert: UIAlertAction) in
self.getMediaFrom(kUTTypeMovie)
}
sheet.addAction(photoLibrary)
sheet.addAction(videoLibrary)
sheet.addAction(cancel)
self.presentViewController(sheet, animated: true, completion: nil)
//let imagePicker = UIImagePickerController()
//imagePicker.delegate = self
//self.presentViewController(imagePicker, animated: true, completion: nil)
}
func getMediaFrom(type: CFString) {
print(type)
let mediaPicker = UIImagePickerController()
mediaPicker.delegate = self
mediaPicker.mediaTypes = [type as String]
self.presentViewController(mediaPicker, animated: true, completion: nil)
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
return messages[indexPath.item]
}
//BUBBLE CHAT
override func collectionView(collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let bubbleFactory = JSQMessagesBubbleImageFactory()
return bubbleFactory.outgoingMessagesBubbleImageWithColor(.lightGrayColor())
}
override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("number of items \(messages.count)")
return messages.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! JSQMessagesCollectionViewCell
return cell
}
override func collectionView(collectionView: JSQMessagesCollectionView!, didTapMessageBubbleAtIndexPath indexPath: NSIndexPath!) {
print("didTappedMessageBubbleAtIndexPath \(indexPath.item)")
let message = messages[indexPath.item]
if message.isMediaMessage {
if let mediaitem = message.media as? JSQVideoMediaItem{
let player = AVPlayer(URL: mediaitem.fileURL)
let playerView = AVPlayerViewController()
playerView.player = player
self.presentViewController(playerView, animated: true, completion: nil)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func LogOutTapped(sender: AnyObject) {
print ("User Logged Out")
//Goes on to Chat View
//Main Stroryboard Interface
_ = UIStoryboard(name: "Main", bundle: nil)
//From MainStoryboard instatiate a navigation controller
let LoginVC = storyboard?.instantiateViewControllerWithIdentifier("LoginVC") as! LogInViewController
//Get app delegate
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
//Navigation Controller as root view controller
appDelegate.window?.rootViewController = LoginVC
}
}
extension ChatViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
print("finish picking")
print(info)
if let picture = info[UIImagePickerControllerOriginalImage] as? UIImage {
let photo = JSQPhotoMediaItem(image: picture)
messages.append(JSQMessage(senderId: senderId, displayName: senderDisplayName, media: photo))
}else if let video = info[UIImagePickerControllerMediaURL] as? NSURL{
let videoitem = JSQVideoMediaItem(fileURL: video, isReadyToPlay: true)
messages.append(JSQMessage(senderId: senderId, displayName: senderDisplayName, media: videoitem))
}
self.dismissViewControllerAnimated(true, completion: nil)
collectionView.reloadData()
}
}
2 ответа
Ошибка говорит вам, что dick["text"]
на самом деле неожиданный ноль.
Попробуйте сделать это:
let text = dick["text"] ?? ""
который должен заменить ноль пустой строкой.
Я хотел бы предложить вам посмотреть на guard
заявление. Это утверждение, которое позволяет вам проверить значение необязательного "?" и если он равен nil, он обрабатывает эту ситуацию, потому что, если у вас нет всей необходимой информации IE сообщений, если в сообщениях нет текста, вы не хотите показывать это в разговоре. Это очень похоже на if let
Заявление, которое вы уже сделали, но делает так, что вам не нужно вкладывать if let
Внутри if let
Поэтому я бы предложил изменить вашу логику на что-то более подобное.
messageRef.observeEventType(.ChildAdded, withBlock: { snapshot in
guard let dick = snapshot.value as? [String: AnyObject] else { return }
// This will return if the snapshot cannot be mapped to the dictionary format [String: AnyObject]
guard let senderId = dick["senderId"] as! String, senderName = dick["senderName"] as! String, text = dick["text"] as! String else { return }
// This will return if the "dick" object does not contain all the elements necessary to create a JSQMessage
// Otherwise we want to add it to our messages list
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, text: text))
self.collectionView.reloadData()
}
Теперь вы также можете посмотреть на эту логику. Ваш dick
объект больше похож на общий объект сообщения. независимо от того, был ли "член" человеком, отправившим сообщение, или нет. Если вы не ссылаетесь на "член" конкретно через ваш путь к firebase
, Судя по всему, эта линия var messageRef = FIRDatabase.database().reference().child("messages")
Я предполагаю, что именно там вы храните все сообщения на вашем бэкэнде. Я, возможно, не полностью понимаю цель здесь, но я надеюсь, что это помогает. Дайте мне знать, если у вас есть дополнительные вопросы.