iosswiftmultipeer-connectivity

How do I detect the decline of a Multipeer Connectivity invitation?


TLDR:

When other devices call the invitationHandler after they receive the invitation, I want the device who sent the invitation to know which device(s) accepted the invitation and which device(s) declined it.

To avoid being an XY problem, here's what I'm doing:

I am using Multipeer Connectivity for a 2-4 player game.

The flow of my app is going to be like this:

This is also why I need to know whether a device declined the invitation. I already know how to detect that a device accepted the invitation, just like this:

func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
    switch state {
    case .connected:
        print("peerID accepted the invitation!")
    default: 
        break
    }
}

I thought there would be a delegate method in MCNearbyServiceBrowserDelegate that handles this. I would imagine that it would be called browser(_:peerDidDeclineInvitation:), but I did not find anything like that.


Solution

  • When user declines the invitation the device that initiated the invite will get a delegate state change with state = MCSessionStateNotConnected.

    As far as I know this state will also happen if user fails to connect for some reason, but you could distinguish the two flows since when connection fails you will also get state change first to MCSessionStateConnecting and then to MCSessionStateNotConnected.

    So in short:

    1. State change from MCSessionStateConnecting toMCSessionStateNotConnected means device failed to connect but invite was accepted
    2. State only goes to MCSessionStateConnecting, means user tapped decline

    Given that you need advanced logic when a game can be started you will not be able to rely on the built in MCBrowserViewController since this will have Done button enabled as soon as one of the peers is coonected.

    You would have to use MCNearbyServiceBrowser then you initiate each invite with -invitePeer:toSession:withContext:timeout: and thus you have a way of knowing who was invited, and based on delegate calls who connected, who failed to connect or who declined.

    Hope this helps...