For my iOS Social Media App project, I am currently working on the Direct Messaging feature of the app. As of making this post, I have the basic functionality working where you can send messages to other users in the app. However, there are a few issues I am experiencing.
1.) When I go to the chat to send a message it shows two text input bars instead of one. It could have something to do with me also using InputBarAccessoryView but I am not sure how to go about removing one of the two input bars so there's only one.
2.) Being able to see the other user's texts and replies. I can send a message to the user but said user won't be able to see it and vice versa for some reason I haven't been able to fetch and load chat history properly.
3.) The chats don't have their own unique messages. If I send a message to one user, it shows up in my chats with other users as well rather than each chat having its own unique messages.
Here is my code associated with Messaging
import UIKit import MessageKit import InputBarAccessoryView import Parse struct Message: MessageType { var sender: SenderType var messageId: String var sentDate: Date var kind: MessageKind } class ChatViewController: MessagesViewController, MessagesDataSource, MessagesLayoutDelegate, MessagesDisplayDelegate, InputBarAccessoryViewDelegate { let currentUser = PFUser.current()! var otherUser: PFUser! var messages = [MessageType]() var inputBar = InputBarAccessoryView() override func viewDidLoad() { super.viewDidLoad() // Set up the other user let query = PFUser.query() query?.whereKey("objectId", notEqualTo: currentUser.objectId!) query?.findObjectsInBackground(block: { (objects, error) in if let users = objects as? [PFUser], let user = users.first { self.otherUser = user // Retrieve previous messages from Parse let messageQuery = PFQuery(className: "Message") messageQuery.whereKey("sender", equalTo: self.currentUser) messageQuery.whereKey("recipient", equalTo: self.otherUser!) let recipientQuery = PFQuery(className: "Message") recipientQuery.whereKey("sender", equalTo: self.otherUser!) recipientQuery.whereKey("recipient", equalTo: self.currentUser) let query = PFQuery.orQuery(withSubqueries: [messageQuery, recipientQuery]) query.findObjectsInBackground { (objects, error) in if let messages = objects { for message in messages { let sender = message["sender"] as! PFUser let text = message["text"] as! String let sentDate = message.createdAt! let messageKind = MessageKind.text(text) let messageSender: Sender do { try sender.fetchIfNeeded() messageSender = Sender(senderId: sender.objectId!, displayName: sender.username ?? "") } catch { messageSender = Sender(senderId: sender.objectId!, displayName: "Unknown") print("Error fetching sender: \(error.localizedDescription)") } let message = Message(sender: messageSender, messageId: message.objectId!, sentDate: sentDate, kind: messageKind) self.messages.append(message) print("Fetched previous messages!") } self.messagesCollectionView.reloadData() self.messagesCollectionView.scrollToLastItem(animated: false) } } } }) // Configure the messages collection view and input bar messagesCollectionView.messagesDataSource = self messagesCollectionView.messagesLayoutDelegate = self messagesCollectionView.messagesDisplayDelegate = self view.addSubview(inputBar) inputBar.delegate = self inputBar.inputTextView.placeholder = "Type a message..." inputBar.sendButton.setTitle("Send", for: .normal) inputBar.sendButton.setTitleColor(view.tintColor, for: .normal) inputBar.sendButton.addTarget(self, action: #selector(sendButtonPressed), for: .touchUpInside) inputBar.translatesAutoresizingMaskIntoConstraints = false inputBar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true inputBar.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true inputBar.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true } func currentSender() -> SenderType { return Sender(senderId: currentUser.objectId!, displayName: currentUser.username ?? "") } func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int { return messages.count } func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType { return messages[indexPath.section] } @objc func sendButtonPressed() { let messageText = inputBar.inputTextView.text.trimmingCharacters(in: .whitespacesAndNewlines) guard !messageText.isEmpty else { return } let message = Message(sender: currentSender(), messageId: UUID().uuidString, sentDate: Date(), kind: .text(messageText)) messages.append(message) inputBar.inputTextView.text = "" messagesCollectionView.reloadData() messagesCollectionView.scrollToLastItem(animated: true) print("Message sent!") // Save the message to Parse let parseMessage = PFObject(className: "Message") parseMessage["sender"] = currentUser parseMessage["recipient"] = otherUser parseMessage["text"] = messageText parseMessage.saveInBackground() print("Message saved!") } func inputBar(_ inputBar: InputBarAccessoryView, textViewTextDidChangeTo text: String) { if text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { inputBar.sendButton.isEnabled = false } else { inputBar.sendButton.isEnabled = true } } func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String) { sendButtonPressed() } }
The above code is for all the messaging functionality such as sending texts, receiving messages, and loading and showing chat history. All help would be greatly appreciated!