IOS Multipeer connectionivity frameworkHandler doesn't seem to accept?

This is my first time using the mutlipeer connection infrastructure, and I want programmatic (not with class helpers) control.

Everything works exactly as described when I run my code on two separate devices until the “advertiser” receives a delegate callback:

The browser client delegate recall call is called when it detects an advertiser:

-(void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info{ [[[UIAlertView alloc] initWithTitle:@"Peer Found" message:peerID.displayName delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] show]; _session = [[MCSession alloc] initWithPeer:_myPeerID]; _session.delegate = self; //connect to the discovered peer. [_browser invitePeer:peerID toSession:_session withContext:nil timeout:30.0]; [_browser stopBrowsingForPeers]; 

}

Then, the ad client delegate callback is called when it receives an invitation:

 -(void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void (^)(BOOL, MCSession *))invitationHandler{ //when my code runs, everything looks correct here. //eg. peerID is definitely my 'browser' client display name etc. _session = [[MCSession alloc] initWithPeer:_myPeerID]; _session.delegate = self; //using a simple version for testing... accept all invites. invitationHandler(YES, _session); //stop advertising now. [_advertiser stopAdvertisingPeer]; } 

After inviting the invitation invitation (YES, _session), it seems that the connection between the view client and the advertisement client is never established.

I never received any delegate callbacks (once or twice I got MCSessionStateNotConnected) in MCSession objects on any client device. I would think that I would get an answer to the MCSession delegate call:

 -(void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state; 

Am I missing something? Anyone else run into this problem?

+8
ios objective-c delegates multipeer-connectivity
source share
4 answers

There is a mistake Apple obviously knows about.

Here's what led to the discovery: Why is my colleague MCSession accidentally disconnected?

You must implement the following delegate callback even if it is listed as optional in the docs ...

 - (void) session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL accept))certificateHandler { certificateHandler(YES); } 
+9
source share

The "didReceiveCertificate" delegation method is optional, and if you do not implement it, the structure assumes that you accept the certificate (note that the certificate may be zero).

However, if you implement the method and then leave it empty, then of course the peer will not connect because the infrastructure expects you to invoke the Handler certificate using YES or NO.

+1
source share

I had similar problems. It seems that if I started the application on one iOS device and connected to another, then close and restart (say, when I switch from Xcode), then I am in a situation where I receive a Connected message, and then the message is not connected a bit later. It threw me away. But looking more closely, I see that the Not Connected message is actually intended for a different peerId than the one that connected.

I think the problem is that most of the samples I saw just care about displayName for peerID and neglect the fact that you can get multiple peerID for the same device / displayName.

Now, I check the displayName first, and then check that the peerID is the same by doing a pointer comparison.

 - (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state { MyPlayer *player = _players[peerID.displayName]; if ((state == MCSessionStateNotConnected) && (peerID != player.peerID)) { NSLog(@"remnant connection drop"); return; // note that I don't care if player is nil, since I don't want to // add a dictionary object for a Not Connecting peer. } if (player == nil) { player = [MyPlayer init]; player.peerID = peerID; _players[peerID.displayName] = player; } player.state = state; ... 
+1
source share

Another problem I discovered (also in other code examples, for example PeerKit) is that stopAdvertisingPeer immediately after the Handler (YES) prompt is probably wrong. Because even you accept the invitation, there is no guarantee that you will be connected. I think it’s better to stop advertising Peer only when connected.

0
source share

All Articles