0

Ich habe eine App, die einen Tab-Leiste-Controller hat. Und in einer Registerkarte befindet sich ein Navigationscontroller, der über einen ViewController verfügt. Jetzt enthält diese Ansicht eine Messaging-Schnittstelle und mein Problem war, dass mit dem Hinzufügen der Tab-Leiste mein Textfeld am unteren Rand der Ansicht abgeschnitten wurde. Um dies zu lösen, habe ich einige der Forschung und einfach hinzugefügt, um die einzelnen Zeile:App stürzt nach Aktion in der Tab-Leiste anzeigen Controller

self.edgesForExtendedLayout = .None

, die das Problem gelöst. Mein Textfeld anzeigte, und der Benutzer kann es auswählen und modifizieren etc. Allerdings, wenn der Benutzer Hits senden, meine App stürzt ab mit der Meldung:

fatal error: unexpectedly found nil while unwrapping an Optional value

Ich habe keine Ahnung, was das Problem, weil alles sein könnte funktioniert perfekt bis dahin ...

Der gesamte Code für meine Viewcontroller wie folgt:

class ChatViewController: JSQMessagesViewController, CLLocationManagerDelegate { 

    // MARK: Properties 

    //Location 
    var city: String = "" 
    var state: String = "" 
    var country: String = "" 
    var locationManager = CLLocationManager() 
    var locationId: String = "" 

    func getLocation() -> String { 
     if city == ("") && state == ("") && country == (""){ 
      return "Anonymous" 
     } 
     else { 
      if country == ("United States") { 
       return self.city + ", " + self.state 
      } 
      else { 
       return self.city + ", " + self.state + ", " + self.country 
      } 
     } 
    } 

    //Firebase 
    var rootRef = FIRDatabase.database().reference() 
    var messageRef: FIRDatabaseReference! 
    var locationRef: FIRDatabaseReference! 

    //JSQMessages 
    var messages = [JSQMessage]() 

    var outgoingBubbleImageView: JSQMessagesBubbleImage! 
    var incomingBubbleImageView: JSQMessagesBubbleImage! 



    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.edgesForExtendedLayout = .None 

     locationManager.delegate = self 
     locationManager.requestWhenInUseAuthorization() 

     if CLLocationManager.locationServicesEnabled() { 
      //collect user's location 
      locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers 
      locationManager.requestLocation() 
      locationManager.startUpdatingLocation() 
     } 

     title = "Group Chat" 
     setupBubbles() 
     // No avatars 
     collectionView!.collectionViewLayout.incomingAvatarViewSize = CGSizeZero 
     collectionView!.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero 

     // Remove file upload icon 
     self.inputToolbar.contentView.leftBarButtonItem = nil; 

     messageRef = rootRef.child("messages") 
     locationRef = rootRef.child("locations") 
    } 

    override func viewDidAppear(animated: Bool) { 
     super.viewDidAppear(animated) 
     observeMessages() 
    } 

    override func viewDidDisappear(animated: Bool) { 
    super.viewDidDisappear(animated) 
    } 


    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
     //--- CLGeocode to get address of current location ---// 
     CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in 

      if let pm = placemarks?.first 
      { 
       self.displayLocationInfo(pm) 
      } 

     }) 

    } 


    func displayLocationInfo(placemark: CLPlacemark?) 
    { 
     if let containsPlacemark = placemark 
     { 
      //stop updating location 
      locationManager.stopUpdatingLocation() 

      self.city = (containsPlacemark.locality != nil) ? containsPlacemark.locality! : "" 
      self.state = (containsPlacemark.administrativeArea != nil) ? containsPlacemark.administrativeArea! : "" 
      self.country = (containsPlacemark.country != nil) ? containsPlacemark.country! : "" 

      print(getLocation()) 

     } 

    } 


    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { 
     print("Error while updating location " + error.localizedDescription) 
    } 


    override func collectionView(collectionView: JSQMessagesCollectionView!, 
           messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! { 
     return messages[indexPath.item] 
    } 

    override func collectionView(collectionView: JSQMessagesCollectionView!, 
           messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! { 
     let message = messages[indexPath.item] // 1 
     if message.senderId == senderId { // 2 
      return outgoingBubbleImageView 
     } else { 
      return incomingBubbleImageView 
     } 
    } 

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

    override func collectionView(collectionView: JSQMessagesCollectionView!, 
           avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! { 
     return nil 
    } 

    private func setupBubbles() { 
     let factory = JSQMessagesBubbleImageFactory() 
     outgoingBubbleImageView = factory.outgoingMessagesBubbleImageWithColor(
      UIColor.jsq_messageBubbleBlueColor()) 
     incomingBubbleImageView = factory.incomingMessagesBubbleImageWithColor(
      UIColor.jsq_messageBubbleLightGrayColor()) 
    } 

    func addMessage(id: String, text: String) { 
     let message = JSQMessage(senderId: id, displayName: "", text: text) 

     messages.append(message) 
    } 

    override func collectionView(collectionView: UICollectionView, 
           cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
     let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath) 
      as! JSQMessagesCollectionViewCell 

     let message = messages[indexPath.item] 

     if message.senderId == senderId { 
      cell.textView!.textColor = UIColor.whiteColor() 
     } else { 
      cell.textView!.textColor = UIColor.blackColor() 
     } 

     return cell 
    } 

    override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!, 
            senderDisplayName: String!, date: NSDate!) { 

     let itemRef = messageRef.childByAutoId() 
     let messageItem = [ 
      "text": text, 
      "senderId": senderId 
     ] 
     itemRef.setValue(messageItem) 

     let locRef = locationRef.childByAutoId() 
     let locItem = [ 
      senderId : [ 
       "location": getLocation() 
      ] 
     ] 

     locRef.setValue(locItem) 

     // Retrieve data from Firebase Realtime database 

     FIRDatabase.database().reference().child("locations").child(senderId).child("location").observeSingleEventOfType(.Value, withBlock: { (snapshot) in 
      self.locationId = snapshot.value!["location"] as! String 
     }) { (error) in 
      print(error.localizedDescription) 
     } 


     JSQSystemSoundPlayer.jsq_playMessageSentSound() 

     finishSendingMessage() 

    } 

    private func observeMessages() { 

     let messagesQuery = messageRef.queryLimitedToLast(25) 

     messagesQuery.observeEventType(.ChildAdded) { (snapshot: FIRDataSnapshot!) in 

      let id = snapshot.value!["senderId"] as! String 
      let text = snapshot.value!["text"] as! String 

      self.addMessage(id, text: text) 

      self.finishReceivingMessage() 
     } 
    } 


    override func textViewDidChange(textView: UITextView) { 
     super.textViewDidChange(textView) 
    } 


    override func collectionView(collectionView: JSQMessagesCollectionView!, attributedTextForCellBottomLabelAtIndexPath indexPath: NSIndexPath!) -> NSAttributedString! { 

     let message = messages[indexPath.item] 

     // Call data I have retrieved below with message 
     let text = "From: " + locationId 

     if message.senderId == senderId { 
      return nil 
     } else { 
      return NSAttributedString(string: text) 
     } 

    } 

    override func collectionView(collectionView: JSQMessagesCollectionView, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout, heightForCellBottomLabelAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
     return kJSQMessagesCollectionViewCellLabelHeightDefault 
    } 


} 

Vielen Dank für jede Hilfe im Voraus!

+0

In welcher Zeile stürzt Ihre App ab? Woher kommt die Variable 'collectionView'? Im Allgemeinen haben Sie eine Menge Kraftauswürfe, '!' Im Code, versuchen Sie, Ihren Code zu überprüfen und umzuformen, um diese zu vermeiden. Dies wird höchstwahrscheinlich Ihren Absturz beheben – Kumuluzz

Antwort

0

Das Problem trat auf, nachdem der Benutzer die Schaltfläche Senden gedrückt hat. Ich habe gerade die Zeile self.edgesForExtendedLayout = .None in die spezifische Aktion hinzugefügt und es hat gut funktioniert!

Verwandte Themen