0

Thanks to the people that helped me on my other SA question, I was able to create a function that returns a boolean to see if a user already voted on a chat message. I want to print if the person voted on the chat message using the MessageKit messageBottomLabelAttributedText function. However, I'm unable to use the returned boolean value to print the correct text.

Here's my current messageBottomLabelAttributedText function within MessagesDataSource:

    func messageBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {

        var bool = didAlreadyVote(message: message as! MessageType){_ in Bool.self}

        if bool as? Bool == true {
            let dateString = self.formatter.string(from: message.sentDate)
            let likeString = "Voted"
            return NSAttributedString(string: "\(dateString) | \(likeString)", attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)])
        } else {
            let dateString = self.formatter.string(from: message.sentDate)
            return NSAttributedString(string: dateString, attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)])
        }
    }
}

For reference, here's the didAlreadyVote function this community helped me out with earlier:

func didAlreadyVote(message: MessageType, completion: @escaping (Bool) -> Void) {

    // check user votes collection to see if current message matches
    guard let currentUser = Auth.auth().currentUser else {return}
    let userID = currentUser.uid
    let docRef = Firestore.firestore().collection("users").document(userID).collection("upvotes").whereField("messageId", isEqualTo: message.messageId)

    docRef.getDocuments { querySnapshot, error in

        if let error = error {
            print("Error getting documents: \(error)")
            completion(false)
        } else {
            for document in querySnapshot!.documents {
                print("\(document.documentID) => \(document.data())")
                completion(true) /// Note that this will get called multiple times if you have more the one document!
            }
        }
    }
}

When I run the app, the bool variable doesn't return anything. How can I retrieve the boolean from the function and then use it within messageBottomLabelAttributedText?

Thanks!

winston
  • 3,000
  • 11
  • 44
  • 75

1 Answers1

1

Don't wait.

didAlreadyVote doesn't return anything. It contains an asynchronous completion handler which passes the Bool value as parameter.

The syntax is

    didAlreadyVote(message: message){ boolValue in   
        if boolValue {
            let dateString = self.formatter.string(from: message.sentDate)
            let likeString = "Voted"
            return NSAttributedString(string: "\(dateString) | \(likeString)", attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)])
        } else {
            let dateString = self.formatter.string(from: message.sentDate)
            return NSAttributedString(string: dateString, attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)])
        }

but you can't use it in messageBottomLabelAttributedText anyway because you can't return anything unless you implement also a completion handler for example

func messageBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath, completion: @escaping (NSAttributedString) -> Void) {
    didAlreadyVote(message: message){ boolValue in   
        if boolValue {
            let dateString = self.formatter.string(from: message.sentDate)
            let likeString = "Voted"
            completion(NSAttributedString(string: "\(dateString) | \(likeString)", attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)]))
        } else {
            let dateString = self.formatter.string(from: message.sentDate)
            completion(NSAttributedString(string: dateString, attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)]))
        }
    }
}
vadian
  • 274,689
  • 30
  • 353
  • 361
  • thanks for the thorough explanation! Trying to absorb this all. So I replaced my `messageBottomLabelAttributedText` function with yours above but now the function isn't being hit at all when I run the app. Does MessageKit ignore it now that the completion handler was added? – winston Mar 04 '19 at 20:58
  • I'm not familiar with MessageKit. If `messageBottomLabelAttributedText` is part of the framework you can't change it and you have to find another way to to handle the asynchronous data. – vadian Mar 04 '19 at 21:00
  • bummer, that's what I was afraid of. Thank you anyways! – winston Mar 04 '19 at 21:00