mandem112
mandem112

Reputation: 191

How to return a Boolean in a completion handler in Swift

I'm trying to refactor my code and would like to return a Bool inside a closure. When I try it says it is unused and doesn't work. I can do it another way but I'm repeating code that I don't want to do. How can I go about it.

func tableView(_ pTableView: UITableView, canEditRowAt pIndexPath: IndexPath) -> Bool {

    // These lines are the one that work but would like to get rid of them
    if let rowConversation = self.objectAtIndexPath(pIndexPath) as? Conversation {
        if rowConversation.isGroupChat && rowConversation.expired  {
            return true
        }
    }

    self.getRowConversation(pIndexPath: pIndexPath) {
        // how to return true here
    }
    return false
}

private func getRowConversation(pIndexPath: IndexPath, completion pCompletion: () -> Void) {
    if let rowConversation = self.objectAtIndexPath(pIndexPath) as? Conversation {
        if rowConversation.isGroupChat && rowConversation.expired  {
            ConversationManager.shared.deleteConversationID(rowConversation.conversationID)
            pCompletion()
        }
    }
}

Upvotes: 0

Views: 1782

Answers (2)

Reinhard Männer
Reinhard Männer

Reputation: 15247

Your problem is that you want to return a result that is produced asynchronously in getRowConversation(pIndexPath: pIndexPath) before it is delivered, i.e. immediately after this function is called in tableView(_ pTableView: UITableView, canEditRowAt pIndexPath: IndexPath) -> Bool.
This is simply not possible, since the result is not yet known at this time.
You had to change (if this is possible) your function tableView(_ pTableView: UITableView, canEditRowAt pIndexPath: IndexPath) -> Bool so that is also has a callback, e.g.
tableView(_ pTableView: UITableView, canEditRowAt pIndexPath: IndexPath, completion: @escaping ((Bool) -> Void)), and to use the result only in the completion block.

Upvotes: 0

matt
matt

Reputation: 535230

You are probably over-thinking this. No "closure" is needed here; no "completion handler" is needed. Nothing asynchronous is happening. Just turn getRowConversation into an ordinary function that returns a Bool; call it and return the result that it passes back to you.

private func getRowConversation(pIndexPath: IndexPath) -> Bool {
    if let rowConversation = self.objectAtIndexPath(pIndexPath) as? Conversation {
        if rowConversation.isGroupChat && rowConversation.expired  {
            ConversationManager.shared.deleteConversationID(rowConversation.conversationID)
            return true
        }
    }
    return false
}

And call it like this:

func tableView(_ pTableView: UITableView, canEditRowAt pIndexPath: IndexPath) -> Bool {
    return self.getRowConversation(pIndexPath: pIndexPath)
}

Upvotes: 7

Related Questions