MSMessagesAppViewController not calling didSelect() properly?

862 views Asked by At

The problem

On iOS 10.2

didSelect() is only called when select a message for the first time, but not for the second time selecting the same message (right after the first select happened). For example:

  1. Click a received MSMessage Message_A while my message app is active, didSelect() method is correctly called and app transit to extended view.
  2. Click down arrow to bring app back to compressed view.
  3. Click the same message - Message_A again, this time didSelect() isn't triggered.

Words From Apple

func didSelect(MSMessage, conversation: MSConversation)

Invoked after the system updates the conversation’s selectedMessage property in response to the user selecting a message object in the transcript.

My thought

It seems selectedMessage isn't updated when we click that message the second time (because it was already set in the first click), thus didSelect() isn't called.

Question

  • Am I doing it wrong?
  • Is there a way to work around and call didSelect() as long as a selection happens? selectedMessage is read only...
  • Or is there a way to make message expire (disappear) from conversation immediately after user opens (clicks) the message?
4

There are 4 answers

0
Jess On

@degapps,

Here is a workaround: After first click on message, didSelect() will take you to expanded view. Now, if a transition to compact view happens, we dismiss this app. It's not a good solution and unlikely to work for most of applications.

override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
    if (presentationStyle == .compact) {
        if let _ = self.activeConversation?.selectedMessage {
            self.dismiss()
        }
    }
}
6
degapps On

I'm afraid it is a bug, there's an open radar for that (or it is done 'by design', taking into account how much time passed since the issue had been filed).

Nevertheless, when message is selected, iMessage's extension is trying to move to expanded mode and calls willTransition(to presentationStyle:) delegate method (which appears to be another bug or cool-thing-by-design). By checking whether the expanded controller has been already shown and tuning your custom flags you may do the trick, although it is not reliable in some cases.

0
quinner On

For those who may need clarity on this question:

didSelect() and willSelect() are only called the first time the message is tapped. Later attempts will not trigger these because the message is already "selected".

The solution is to call extensionContext.open(url) in a willBecomeActive() overriding function like so

override func willBecomeActive(with conversation: MSConversation) {
    // Called when the extension is about to move from the inactive to active state.
    // This will happen when the extension is about to present UI.
    
    // Use this method to configure the extension and restore previously stored state.
    if let url = conversation.selectedMessage?.url {
        self.extensionContext?.open(url)
    }

This ensures the message will open every time it's tapped because it has already become active after activation. It's important to keep in mind the difference between Activation and Selection here; activation can be "toggled" on and off whilst selection can just occur one time.

2
iArezki On

I have the same problem, the didSelect() and willSelect() methods are called only once. I circumvented this problem by implementing my logic in the method :

Objective C

-(void)didBecomeActiveWithConversation:(MSConversation *)conversation

Swift

func didBecomeActive(with conversation: MSConversation)