I'm developing a turn-based Messages game extension and experiencing a persistent issue on iPad where tapping on message bubbles does not reliably trigger lifecycle callbacks after the extension has been used once.
The Problem:
On iPad, after a player:
Opens the extension by tapping a game message
Takes their turn (plays a card)
Sends the updated game state as a new message
Extension collapses
When the opponent sends their response and the player taps on the new message bubble, the extension often does not open. The didSelect(_:conversation:) method is not called. The user must refresh the conversation by scrolling away and back or reopening the Messages App before tapping works again. This works perfectly on iPhone - every tap on a message bubble reliably triggers didSelect and opens the extension.
What I've Tried:
I've implemented every lifecycle method and workaround I could find:
swiftoverride func willBecomeActive(with conversation: MSConversation) {
super.willBecomeActive(with: conversation)
if let message = conversation.selectedMessage, let url = message.url {
loadGameState(from: url, message: message, conversation: conversation)
}
}
override func didBecomeActive(with conversation: MSConversation) {
super.didBecomeActive(with: conversation)
if let message = conversation.selectedMessage, let url = message.url {
loadGameState(from: url, message: message, conversation: conversation)
}
}
override func didSelect(_ message: MSMessage, conversation: MSConversation) {
// This is NOT called on iPad when tapping message bubbles
guard let url = message.url else { return }
loadGameState(from: url, message: message, conversation: conversation)
}
override func didReceive(_ message: MSMessage, conversation: MSConversation) {
guard let url = message.url else { return }
loadGameState(from: url, message: message, conversation: conversation)
}
override func didTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
super.didTransition(to: presentationStyle)
// Attempted to reload here as well
}
I also tried:
Observing NSExtensionHostDidBecomeActive and NSExtensionHostWillEnterForeground notifications
Forcing UI refresh in viewDidLayoutSubviews
Checking conversation.selectedMessage in every lifecycle method
Research:
I found several Developer Forums threads from 2016 describing this exact issue:
Thread 53167: "MSMessagesAppViewController.didSelect not called on message reselect"
Thread 60323: "willSelectMessage and didSelectMessage don't fire"
An Apple staff member confirmed that didSelect only fires when selecting a different message, similar to UITableView selection behavior. However, on iPad, it seems like messages remain "selected" even after the extension collapses, so tapping a new message doesn't register as a new selection.
Questions:
Is there a recommended way to detect when a user taps a message bubble on iPad, even if iOS considers a message "already selected"?
Is there a way to programmatically deselect the current message (similar to UITableView.deselectRow) so that subsequent taps trigger didSelect?
Are there any iPad-specific lifecycle methods or notifications I should be observing?
Is this a known limitation of the Messages framework on iPad?
Environment:
Xcode 16
iOS 18 and 26
Testing on iPad Pro (M4) and iPad Air
iPhone works correctly on all tested devices
Any guidance would be greatly appreciated. This is blocking our App Store submission as reviewers are flagging the iPad behavior as incomplete functionality.
2
0
78