Further investigation has turned up some interesting things:
The docs say a match will be cancelled if declined. So this may not be desirable. This status is CLEARLY not being set when a user long touches their push notification and then taps Decline.
Setting timeout works as expected on GKTurnBasedMatch.endTurn(...) whether the players ignore the invite OR tap to Decline in the notification.
My take away is to assume we can only handle positive actions (acceptance of invite by completing action that causes my app to endTurn for that player) and timeouts with the host player being the last participant in the nextParticipants array so they can do something.
My guess, to answer my own question, is that there is no way to know this has happened and that either this is completely a no-op from a Game Center or Turn Based Match perspective.
I think this is not GREAT per se, but is fine for sure. I also think my expectation that I can plan out every possible situation is too expansive and should be set to let the host know at some point that all they can do is delete the match, wait it out, or ignore it.
I think an article in the docs to cover the various paths OTHER than the expected happy path would be great. Overall, the docs do seem to be pretty solid, but sometimes it is hard to find things. Maybe this is just me? 🤦♀️
I am leaving this open in case someone can definitively shed light on if there is a way to find out if this decline via notification happens OR what happens with Game Center, if anything.
Post
Replies
Boosts
Views
Activity
Further investigation shows that status of invited participants is .matching until they accept in the push notification panel or take action leading to their turn being ended by calling endTurn(...). Tapping decline leads to a status for that participant of .invited. If a player misses the push or otherwise ignores it, they remain .matching.
So to answer my question:
Participant States based on Actions WRT the Invite Message Game Center Push Notification:
.matching is starting status
.matching remains after push is seen and ignored or otherwise missed.
.invited if the user taps "Decline"
.active if the user taps "Accept", even if they do not take any action in the app OR the app does something on the player's behalf.
After end of year distractions I've come back to working on this and have a couple of interesting new observations while testing a 3 player match (1 hostess and 2 friend invitees):
When the first invitee taps the push notification or taps to accept in the push notification actions, their status becomes .active. This means that this player has no way of NOT accepting if they interact at all with the push notification. Ugh.
When the second invitee taps the push notification, taps accept in the push notification actions, OR taps a button in my app to Accept the invitation that calls .acceptInvite() on the match's GKTurnBasedMatch instance, their status remains .matching.
This is frustrating because joining the match works differently for these two invitees. Both devices (iPad 6thG & iPhone SE 2ndG) are on iPadOS/iOS 17.5.1. Technically it is possible hardware matters here, but I feel this is unlikely.
The approach I was taking was for participant[0] (the hostess) to endTurn with all participants (1, 2, and 0 in that order) and a short time out (30s). During each participant's turn, they're presented with a button to accept the invite that only calls .acceptInvite() on the GKTurnBasedMatch instance. This should theoretically be actionable out of turn. The hostess is expected to be "in turn" before all the invites have been accepted and can see who has accepted and how many invites are outstanding. This felt like a good way to not require serial invitations and responses and to keep the hostess updated on the status of their new match.
I think the approach I'm going to have to take is go back to the original implementation where I ignored participant status and just invite each player and let them endTurn(_:) as they join. The only differences is I will check for .invited status and treat that as a declined invite AND allow the player to decline in the app which I can use to let the hostess know the match is over. The reason I rejected this is because a declined invite seemed difficult to identify. (As per the accepted answer, this is via participant.status == .invited) Also, I did not code for declines (tho that was what I was starting to work on when I posted this question.)