简体   繁体   中英

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:

  • Devices can set their visibility to others by pressing a button
  • One of the 2-4 players of the game, let's call him Player A, will press a button and he/she will see a list of nearby players
  • Player A will choose 1-3 players from the list that he wants to add to the game
  • Other devices use some logic to figure out whether to accept the invitation or decline it.
  • After all the invitations Player A sent has been responded to, a button will be enabled and Player A can press it to start the game.
  • I am doing this since I don't want new players joining after the game starts. If for example, Player A invites Player B and Player B accepts it. Player A then invites Player C but before Player C receives the invitation, Player A starts the game. The game will start but because only 2 players are connected, a 2-player game will be created. After that the invitation reaches Player C and he accepts it and now suddenly there are 3 people in a 2-player game! This is why I need to ensure all invitations are responded before starting the game.

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.

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 to MCSessionStateNotConnected 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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM