Question

I'm working on an app the uses the Multipeer Conectivity Framework. So far everything is going great, I've implemented programmatic browsing and invitations.

My issue is when the user accepts the invitation the Browser is not receiving the state change - thereby not creating the session.

This is the advertiser did receive invitation method i have created using an action sheet integrated with blocks.

    - (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser
didReceiveInvitationFromPeer:(MCPeerID *)peerID
       withContext:(NSData *)context
 invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler
{

    [UIActionSheet showInView:self.view
                    withTitle:[[NSString alloc]initWithFormat:@"%@ would like to share %@ information with you.",peerID.displayName, (NSString *)context]
            cancelButtonTitle:@"Cancel"
       destructiveButtonTitle:@"Deny"
            otherButtonTitles:@[@"Accept"]
                     tapBlock:^(UIActionSheet *actionSheet, NSInteger buttonIndex) {
                         NSLog(@"%i",buttonIndex==1?true:false);
                         MCSession *newSession=[[MCSession alloc]initWithPeer:[[MCPeerID alloc] initWithDisplayName:@"CRAP23456"]];
                         [newSession setDelegate: self];
                         NSLog(@"button index %i ",buttonIndex==1?true:false);
                         invitationHandler(buttonIndex==1?YES:NO,newSession);
                     }];
}

The above method is being called and the invitation handler is returning the correct value.

My implementation from the browser side is very simple - and this is the method that should be called when the user either accepts/declines the method. However, it's only being called when the user declines the invite:

 - (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
{
    NSLog(@"%d",state);
    NSLog(@"%ld",(long)MCSessionStateConnected);
}

Thanks in advance.

James.

Was it helpful?

Solution 2

I ran into this issue too. My code on the browser side looked like this:

MCSession *session = [[MCSession alloc] initWithPeer:[self peerID]];
session.delegate = self;
[browser invitePeer:peerID toSession:session withContext:nil timeout:30.0f];

The issue with this is that the browser does not retain a reference to the session and so ARC comes around and cleans it up before the other end had the opportunity to accept.

Changing it to the following fixed the issue:

_session = [[MCSession alloc] initWithPeer:[self peerID]];
_session.delegate = self;
[browser invitePeer:peerID toSession:_session withContext:nil timeout:30.0f];

.. where _session is an ivar on my class.

HTH

OTHER TIPS

I hope one of these will help:

  • Implement session:didReceiveCertificate:fromPeer:certificateHandler: I read here that this is necessary.

  • Keep browsing and advertising between two peers a one-way deal; that is, don't accept invitations on both ends if both are browsing as well (at least don't accept an invitation and pass same session you're browsing with in invitationHandler()).

  • Wrap your code in the didChangeState in a block like this: dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"%d",state); NSLog(@"%ld",(long)MCSessionStateConnected); });

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top