MSMessagesAppViewController.didSelect(message:conversation:) not called on message reselect

I've noticed that if you select a Messages app extension message, collapse to compact presentation mode, then select it again

willSelect(message:conversation:)
is not called on the second select. Neither is
didSelect(message:conversation:)
.


Both also fail to call if you insert a message, send it, then select that same message.


Is this expected behavior?


If it is, how do you detect the difference between the user tapping a message that is already selected, and a user tapping the expand presentation mode control? And how do you detect the difference between the user tapping a message that is already selected, and a user starting your app from the Messages app drawer?


I filed a bug because it does not seem like the documented behavior.

Open radar: 27621637


(Edited for formatting.)

Collapsing to compact mode wouldn't change the state of the selected message so I wouldn't expect it to call the will/didSelect messages if you're trying to tap on the same message. If you tap on a single message I would only expect to get the will/didSelect if you select a different message. This is similar to how a table view works. Once a row is selected, you won't get repeated will/didSelect messages if you tap on the same row (on an iPad, for example where you've got master and detail view on screen simultaneously).


The selected message and the presentation mode are orthoganal. If you need to keep track of the selected messages, stash use the selectedMessage property of the conversation.


Thank you for the bug, we can use that to clarify the documentation since this caused some confusion.

Yes, this makes sense to me. But a UITableView allows me to programmatically deselct a table row via

deselectRow(at:animated:)
.


Can we programatically deselect a message with the Messages framework?


The rather mundane reason for this is to allow the user to back out of a selected message view to a collection browsing view (ala the Apple IceCreamBuilder example app). As it stands, if the user backs out to a browse view, then taps the selected message again, we have no way to detect that tap versus a tap on the "expand" carrot control.


The IceCreamBuilder app addresses this by always entering a selected message view when detecting a presentation style change to .expanded. And if there isn't a selected message, it just starts a new one. But this strikes me as an unintuitive UI response. If the user is in browse mode and presses "expand", she would expect it to show an expanded browse mode, not a view of a message she just backed out of. And not a view of a new message. The expand carrot is not a web browser "forward" button. And it's not a "create new message" button. But that is how it acts in the IceCreamBuilder app. And since the user has no indication whether a message is selected or not, she won't even know which one.


This could be solved in either of two ways.

(1) Allow us to programatically deselect a message when the user backs out to a browse mode, or

(2) Let us detect when a user taps a message, even if the message is already selected.


But it seems neither of those is available.


Other developers seem to expect this functionality as well:

MSMessagesAppViewController overridden willSelect is never called

That radar: 27392203


(Edited for formatting.)

You make an excellent point. This is a HUGE problem for us and I am not sure why this is not being addressed. I have an imessage app currently under development and if this is not addressed then the app is a no go.

Did you figure out any work around for this issue? Any help is highly appreciated.

Unfortunately no, I haven't found a workaround. I'm following a few other threads on the same issue, but haven't heard any good suggestions. But this is the only one I've found with a response from Apple staff.


No movement on the bug report I submitted July 29 either. 27621637.


Other threads, same issue.

Having the same problem. Really frustrating because once the user selects a message, the property will be always true. This property should only be true in -willBecomeActive or a lifecycle method so that the developer can manually cache the selectedMessage and do whatever they prefer manually. If the user then interacts with the extension, the property should be immediately nilled out.

I'd prefer a

deselectSelectedMessage()
method on
MSConversation
, but either would enable some kind of workaround.

Presuming no workaround is available, here is an idea for making this problem less confusing for the user. For a

collection view <-> single message view

structure, similar to the IceCreamBuilder example code.


As in IceCreamBuilder,

compact
presentation is always the collection view,
expanded
presentation is always the single message view.


At the top of the collection, keep an undeletable "new message" item. If

activeConversation?.selectedMessage?
exists, add a second undeletable "selected message" item. Always subtly highlight the "selected message" item if it exists, otherwise always subtly highlight the "new message" item.


If

willTransition(to: .expanded)
fires without the user selecting from the collection, provide a bit of "this item got pressed" animation on the highlighted item and open it.


I don't like this solution because I plan to have a "what you were just looking at" item appear in the collection view if the user collapses via the compact chevron control. I'd prefer "what you were just looking at" then be selected. But I can't do that, because I can't change what message is selected. So if the user does this:

(1) Tap a message in conversation

(2) Back out to collection view

(3) Pick an old item from collection view history

(4) Collapse to collection view

(5) Immediately expand to single view

It's not going to open what they were just looking at. It's going open the selected message. Because there is no way for me to detect whether they pressed "expand" or they pressed the message in conversation again.


So this solution is imperfect.

Having the same issue. This is confusing as a user. I have a collection view with data, and a search bar in my iMessage app. When selecting the search bar, I expand the app, as that is the only way to use the keyboard in the iMessage app, but if the user previously selected a message, it presents details now instead of the same interface. I tried fixing this by caching the selected message myself as a variable, but then `func didSelect(_ message: MSMessage, conversation: MSConversation)` seems to never be called for me, even if selecting a different show. So the current solution is now disable viewing info for selected messages because of this issue.

I am having the same issue. When the user selects an existing message, I would like to display some details about that message. It seems very unintuitive that on tapping a message, the user sees expanded view.

Wouldn't it be a lot easier for an app that only cares about the first tap to ignore subsequent didSelectMessage calls, than it is for an app that wants to respond to every tap to infer them from display transitions?

MSMessagesAppViewController.didSelect(message:conversation:) not called on message reselect
 
 
Q