I followed this tutorial on MultiPeerConnectivity (MCF) and list most tutorials online, they took the shortcut of using the services of MCAdvertiserAssistant and MCBrowserViewController
I tried implementing the same tutorial but with using MCNearbyServiceAdvertiser and MCNearbyServiceBrowser instead because i'm interested in customizing the discoverability on my app.
things work fine as far as listing the nearby devices.. but then the trouble starts in the MCNearbyServiceAdvertiserDelegate
where I call this method:
- (void) advertiser:(MCNearbyServiceAdvertiser *)advertiser
didReceiveInvitationFromPeer:(MCPeerID *)peerID
withContext:(NSData *)context
invitationHandler:(void (^)(BOOL, MCSession *))invitationHandler {
// Allow the peer to join this Vibereel
MCSession *peerSession = [[MCSession alloc] initWithPeer:_peerID];
peerSession.delegate = self;
invitationHandler(YES, peerSession);
NSLog(@"Accepted entry request for peer %@", [peerID displayName]);
}
this does not trigger the did change state method:
-(void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
although it did with the original versions.
I know I obviously need to put more code to demonstrate the problem.. and so I created a github repo that started with the original code. This is the commit that adds the custom made browser along with the custom UITableViewController to display nearby devices (works fine) and here is the commit that does the advertising (doesn't work)
Make the peerSession a property of the class instead of a local variable of the method. The problem is that in your code the peerSession is released at the end of the method. I have a working example on my blog.
Couple of thoughts here after checking out code on you repo, I'm sure that this issue is mostly todo with the way how you've your MCSession
object setup. I agree with Peter here, you should have one session object common across the flow as a strong reference.
Secondly, since you're trying to get things working with just MCNearbyServiceBrowser
& MCNearbyServiceAdvertiser
, you'd need to make sure the flow is rightly setup in general. Once you found a peer via the following callback,
- (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info;
invite the peer using [browser invitePeer:peerID toSession:self.session withContext:nil timeout:0];
now at the peer end you'd receive a callback on the following delegate,
- (void) advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID
withContext:(NSData *)context
invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler
and you accept the invitation by confirming to invitationHandler(YES, session)
(as you doing it above), if you've your session object common across the flow, this should get - (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
triggered with MCSessionStateNotConnected
then MCSessionStateConnecting
state. Now, on the first peer you will receive the following delegate callback
- (void)session:(MCSession *)session
didReceiveCertificate:(NSArray *)certificate
fromPeer:(MCPeerID *)peerID
certificateHandler:(void(^)(BOOL accept))certificateHandler;
and here you should be confirming via setting the certificateHandler(YES)
to establish the connection. This is the last very important piece, specially when you're trying to get the whole thing working without the factory provided view controllers.
I know this isn't easy to get it working for the first time, but it gets easy along the way. Please mention me in comments, I'll reply you back for any clarification.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With