How does the MCNearbyServiceBrowser know if the MCNearbyServiceAdvertiser invitation has declined the invitation?

Question about connecting IOS Multipeer ...

If MCNearbyServiceAdvertiser rejects the invitation from MCNearbyServiceBrowser through a call:

invitationHandler(NO, nil);

... in:

advertiser:didReceiveInvitationFromPeer:withContext:invitationHandler:

... is there a way for MCNearbyServiceBrowser know that the invitation has been specifically rejected ?

I see that a device using MCNearbyServiceBrowser gets a session state change to MCSessionStateNotConnected when the advertiser declines the invitation, but I would suggest that the browser might receive MCSessionStateNotConnected for other reasons ... as the advertiser’s device quits (turned off, etc.).

Any suggestions on how to distinguish a declined invitation from any other disconnect?

Thanks.

-Allan

+6
source share
1 answer

According to docs, MCSessionStateNotConnected may mean that

"... a neighboring peer rejected the invitation, the connection could not or the previously connected peer is no longer connected."

You are not saying in your question what will lead to the rejection of the invitation, but assuming that it is user-driven, one approach could be that your MCNearbyServiceAdvertiserDelegate automatically accepts the invitation, creating a new session for each peer, and then presents the user with the opportunity to accept or reject the connection. Your colleagues will not be considered truly in a session with each other until they receive a subsequent message indicating the user's decision:

So, in the MCNearbyServiceAdvertiserDelegate class, which you would accept, and then query the user:

 - (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler { //Automatically accept with a new session MCSession *newSession = [[MCSession alloc] initWithPeer:_myPeerID]; newSession.delegate = self; //Keep track of the pending sessions in a mutable dictionary _pendingSessionPeerIDMap[peerID.displayName] = newSession; invitationHandler(YES,newSession); /* Code here to present user with option to accept or decline peer */ } 

And then, when the user answered, you could have a method that sends a simple string in the form of NSData containing the status:

 @property NSData *inviteAcceptedMsgData = [@"MPCInviteYES" dataUsingEncoding:NSUTF8StringEncoding]; @property NSData *inviteDeclinedMsgData = [@"MPCInviteNO" dataUsingEncoding:NSUTF8StringEncoding]; - (void)invitationFromPeerID:(MCPeerID *)peerID receivedResponse:(BOOL)accepted { //Send a message to the peer that sent the invitation indicating whether the //user accepted or declined NSData *msgData = (accepted) ? _inviteAcceptedMsgData : _inviteDeclinedMsgData; MCSession *peerSession = _pendingSessionPeerIDMap[peerID.displayName]; [peerSession sendData:msgData toPeers:@[peerID] withMode:MCSessionSendDataReliable error:nil]; //Remove the pending session [_pendingSessionPeerIDMap removeObjectForKey:peerID.displayName]; //And if the connection was accepted by the user, add to an accepted dictionary _acceptedSessionPeerIDMap[peerID.displayName] = peerSession; } 

MCNearbyServiceBrowserDelegate will work in a similar way:

 - (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info { //Send the invitation with a new session MCSession *newSession = [[MCSession alloc] initWithPeer:_myPeerID]; newSession.delegate = self; [browser invitePeer:peerID toSession:newSession withContext:nil timeOut:0]; } 

The browser will then wait for a message from the invited partner to determine if the invitation was actually accepted:

 - (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID { //Check the data to see whether invite was accepted if ([data isEqualToData:_inviteAcceptedMsgData]) { //Add to an accepted dictionary _acceptedSessionPeerIDMap[peerID.displayName] = session; } else if ([data isEqualToData:_inviteAcceptedMsgData]){ //Disconnect the session [session disconnect]; } } 

You may already have a messaging system, but this is a simple implementation of the transfer state between connected peers. Regarding sending broadcast messages or displaying connected peers, _acceptedSessionPeerIDMap should be used as a true collection of peers.

+5
source

Source: https://habr.com/ru/post/971483/


All Articles