ios - Firebase & JSQMessagesViewController 在 Ios Swift 2 中的一对一聊天

标签 ios swift firebase firebase-realtime-database jsqmessagesviewcontroller

所以我正在尝试在正在构建的应用程序中实现一对一聊天系统,但遇到了一些麻烦。这是我目前所拥有的。

这是我的代码

请帮助我,我也非常感谢任何示例。谢谢

`

import UIKit
import JSQMessagesViewController
import Firebase

class MessagesViewController: JSQMessagesViewController {


    var messages = [Message]()
    var userImage = ""
    var toUser: String!
    var toUserImageUrl: String!
    var avatars = Dictionary<String, UIImage>()
    var outgoingBubbleImageView: JSQMessagesBubbleImage!
    var incomingBubbleImageView: JSQMessagesBubbleImage!
    var senderImageUrl: String!
    var batchMessages = true
//    var ref: Firebase!

    // *** STEP 1: STORE FIREBASE REFERENCES
    var messagesRef: FIRDatabaseReference!

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

    override func viewDidLoad() {
        super.viewDidLoad()

print(toUser)

        inputToolbar.contentView.leftBarButtonItem = nil
        automaticallyScrollsToMostRecentMessage = true
       // self.collectionView.backgroundColor = UIColor.blackColor()
        self.navigationItem.hidesBackButton = true
        let newBackButton = UIBarButtonItem(title: "< Back", style: UIBarButtonItemStyle.Bordered, target: self, action: #selector(MessagesViewController.back(_:)))
        self.navigationItem.leftBarButtonItem = newBackButton;
        self.navigationController?.navigationItem.leftBarButtonItem?.tintColor = UIColor.whiteColor()

        senderId = (senderId != nil) ? senderId : "Anonymous"
        if let urlString = userImage as? NSString {
            setupAvatarImage(senderId, imageUrl: senderImageUrl, incoming: false)
            senderImageUrl = urlString as String
        } else {
            setupAvatarColor(senderDisplayName, incoming: false)
            senderImageUrl = ""
        }

        senderId = Constants.currentUser

        self.title = toUser

        // No avatars
        collectionView!.collectionViewLayout.incomingAvatarViewSize = CGSizeZero
        collectionView!.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero

        setupBubbles()
        setupFirebase()
    }

    func back(sender: UIBarButtonItem) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }

    func setupFirebase() {
        // *** STEP 2: SETUP FIREBASE
        messagesRef = FIRDatabase.database().reference()

        // *** STEP 4: RECEIVE MESSAGES FROM FIREBASE (limited to latest 25 messages)

        messagesRef.observeEventType(.ChildAdded, withBlock: { (snapshot) -> Void in
                        let text = snapshot.value!["text"] as? String
                        let sender = snapshot.value!["from"] as? String
                        let toUsername = snapshot.value!["toUser"] as? String
                        let senderimageUrl = snapshot.value!["senderimageUrl"] as? String
                        let toUserImageUrl = snapshot.value!["toUserimageUrl"] as? String

                        let message = Message(text: text, sender: sender, toUsername: toUsername, senderimageUrl: senderimageUrl, toUserimageUrl: toUserImageUrl)
                        self.messages.append(message)
                        self.finishReceivingMessage()
        })

    }

    func sendMessage(text: String!, sender: String!, to: String!) {
        // *** STEP 3: ADD A MESSAGE TO FIREBASE


        messagesRef.childByAutoId().setValue([
            "text":text,
            "toUser":toUser,
            "from":self.senderId,
            "senderimageUrl":senderImageUrl,
            "toUserimageUrl":toUserImageUrl
            ])
    }

    func tempSendMessage(text: String!, sender: String!, to: String!) {
        let message = Message(text: text, sender: sender, toUsername: to, senderimageUrl: senderImageUrl, toUserimageUrl: toUserImageUrl)
        messages.append(message)
    }


    func setupAvatarImage(name: String, imageUrl: String?, incoming: Bool) {
        if let stringUrl = imageUrl {
            if let url = NSURL(string: stringUrl) {
                if let data = NSData(contentsOfURL: url) {
                    let image = UIImage(data: data)
                    let diameter = incoming ? UInt(collectionView.collectionViewLayout.incomingAvatarViewSize.width) : UInt(collectionView.collectionViewLayout.outgoingAvatarViewSize.width)
                    let avatarImage = JSQMessagesAvatarImageFactory.avatarImageWithImage(image, diameter: diameter).avatarImage
                    avatars[name] = avatarImage
                    return
                }
            }
        }

        // At some point, we failed at getting the image (probably broken URL), so default to avatarColor
        setupAvatarColor(name, incoming: incoming)
    }

    func setupAvatarColor(name: String, incoming: Bool) {
        let diameter = incoming ? UInt(collectionView.collectionViewLayout.incomingAvatarViewSize.width) : UInt(collectionView.collectionViewLayout.outgoingAvatarViewSize.width)

        let rgbValue = name.hash
        let r = CGFloat(Float((rgbValue & 0xFF0000) >> 16)/255.0)
        let g = CGFloat(Float((rgbValue & 0xFF00) >> 8)/255.0)
        let b = CGFloat(Float(rgbValue & 0xFF)/255.0)
        let color = UIColor(red: r, green: g, blue: b, alpha: 0.5)

        let nameLength = name.characters.count
        let initials : String? = name.substringToIndex(toUser.startIndex.advancedBy(min(3, nameLength)))
        let userImage = JSQMessagesAvatarImageFactory.avatarImageWithUserInitials(initials, backgroundColor: color, textColor: UIColor.blackColor(), font: UIFont.systemFontOfSize(CGFloat(13)), diameter: diameter).avatarImage

        avatars[name] = userImage
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        collectionView.collectionViewLayout.springinessEnabled = true
    }

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)

//        if ref != nil {
//            ref.unauth()
//        }
    }

    // ACTIONS

    func receivedMessagePressed(sender: UIBarButtonItem) {
        // Simulate reciving message
        showTypingIndicator = !showTypingIndicator
        scrollToBottomAnimated(true)
    }

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

        sendMessage(text, sender: senderId, to: toUser)

        finishSendingMessage()
    }

    override func didPressAccessoryButton(sender: UIButton!) {
        print("Camera pressed!")
    }


    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() == self.senderId{ // 2
            return outgoingBubbleImageView
        } else { // 3
            return incomingBubbleImageView
        }
    }

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

    func collectionView(collectionView: JSQMessagesCollectionView!, bubbleImageViewForItemAtIndexPath indexPath: NSIndexPath!) -> UIImageView! {
        let message = messages[indexPath.item]

        if message.senderId() == self.senderId {
            return UIImageView(image: outgoingBubbleImageView.messageBubbleImage, highlightedImage: outgoingBubbleImageView.messageBubbleHighlightedImage)
        }

        return UIImageView(image: incomingBubbleImageView.messageBubbleImage, highlightedImage: incomingBubbleImageView.messageBubbleHighlightedImage)
    }

    func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageViewForItemAtIndexPath indexPath: NSIndexPath!) -> UIImageView! {
        let message = messages[indexPath.item]
        if let avatar = avatars[message.senderId()] {
            return UIImageView(image: avatar)
        } else {
            setupAvatarImage(message.senderId(), imageUrl: message.senderimageUrl(), incoming: true)
            return UIImageView(image:avatars[message.senderId()])
        }
    }

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


    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() == self.senderId {
            cell.textView.textColor = UIColor.whiteColor()
        } else {
            cell.textView.textColor = UIColor.blackColor()
        }

        let attributes : [String:AnyObject] = [NSForegroundColorAttributeName:cell.textView.textColor!, NSUnderlineStyleAttributeName: 1]
        cell.textView.linkTextAttributes = attributes

        //        cell.textView.linkTextAttributes = [NSForegroundColorAttributeName: cell.textView.textColor,
        //            NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleSingle]
        return cell
    }


    // View  usernames above bubbles
    override func collectionView(collectionView: JSQMessagesCollectionView!, attributedTextForMessageBubbleTopLabelAtIndexPath indexPath: NSIndexPath!) -> NSAttributedString! {
        let message = messages[indexPath.item];

        // Sent by me, skip
        if message.senderId() == self.senderId {
            return nil;
        }

        // Same as previous sender, skip
        if indexPath.item > 0 {
            let previousMessage = messages[indexPath.item - 1];
            if previousMessage.senderId() == message.senderId() {
                return nil;
            }
        }

        return NSAttributedString(string:message.senderId())
    }

    override func collectionView(collectionView: JSQMessagesCollectionView!, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout!, heightForMessageBubbleTopLabelAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
        let message = messages[indexPath.item]

        // Sent by me, skip
        if message.senderId() == self.senderId {
            return CGFloat(0.0);
        }

        // Same as previous sender, skip
        if indexPath.item > 0 {
            let previousMessage = messages[indexPath.item - 1];
            if previousMessage.senderId() == message.senderId() {
                return CGFloat(0.0);
            }
        }

        return kJSQMessagesCollectionViewCellLabelHeightDefault
    }



}

`

最佳答案

所以我建议检查

只需打开 SwiftExample.xcworkspace 即可在 SwiftExample 文件夹中找到 Swift 示例。

https://github.com/jessesquires/JSQMessagesViewController

它是 JSQMessagesViewController 的一部分,目前正在维护。还有一个群组和一对一对话的例子。这应该可以帮助您完成私有(private)对话。但我认为您缺少一个关键组件,即您的对话 View 。那就是您发起对话的地方。然后你应该在你的 firebase 后端有一个端点,你可以为用户之前进行的所有对话点击它。这样他们就可以再次打开它们。

关于ios - Firebase & JSQMessagesViewController 在 Ios Swift 2 中的一对一聊天,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39067880/

相关文章:

android - Firestore - 如何使用路径字符串创建 DocumentReference

firebase - 执行 flutter run 时获取此日志输出的原因是什么 - 与设备失去连接 - ?

objective-c - 如何结束使用 detachNewThreadSelector 创建的轮询线程?

ios - 如何在 AspectFit 比例后调整 UIImageView 的大小

swift - 在 Swift 中有选择地从 NSMutableArray 中移除和删除对象

ios - 在 iOS 中为推送通知发送报告

swift - CAShapeLayer 填充颜色将保持白色

ios - 在 iOS 中传递上下文以将 Core Data 与 Storyboard 一起使用

ios - 在理解部分块时遇到问题

Firebase 规则通配符和子项比较