I hope I am not violating NDA by posting this question.
I am using the new multipeer connectivity to send using bluetooth some files to nearby devices. I have managed to send invitations, but I don't seem to get how to display a UIAlertView where the user can accept or decline the invite. Right now when a user sends, the file is automatically saved and there is no accept/decline alert.
The code is:
- (void) advertiser:(MCNearbyServiceAdvertiser *)advertiser
didReceiveInvitationFromPeer:(MCPeerID *)peerID
withContext:(NSData *)context
invitationHandler:(void(^)(BOOL accept,
MCSession *session))invitationHandler{
... save the data context
but with the alert:
- (void) advertiser:(MCNearbyServiceAdvertiser *)advertiser
didReceiveInvitationFromPeer:(MCPeerID *)peerID
withContext:(NSData *)context
invitationHandler:(void(^)(BOOL accept,
MCSession *session))invitationHandler{
DevicePeer = [MCPeerID alloc];
DevicePeer = peerID;
ArrayInvitationHandler = [NSArray arrayWithObject:[invitationHandler copy]];
// ask the user
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:@""
message:@""
delegate:self
cancelButtonTitle:@"NO"
otherButtonTitles:@"YES", nil];
[alertView show];
alertView.tag = 2;
}
and the alert view method:
- (void) alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex
{
// retrieve the invitationHandler
// get user decision
BOOL accept = (buttonIndex != alertView.cancelButtonIndex) ? YES : NO;
// respond
MCSession *session = [ArrayInvitationHandler objectAtIndex:0];
void (^invitationHandler)(BOOL, MCSession *) = [ArrayInvitationHandler objectAtIndex:0];
invitationHandler(accept, session);
}
When the user press YES the app crashes and I get the error:
[__NSMallocBlock__ nearbyConnectionDataForPeer:withCompletionHandler:]: unrecognized selector sent to instance 0x14d4e3b0'
I have looked up at the IOS developer library and there is no such method apart from
- (void)nearbyConnectionDataForPeer:(id)arg1 withCompletionHandler:(id)arg2{
}
which does no work. No info on the IOS developer forums. Any ideas?
Alessandro is right, this is not explained in the WWDC 2013 video. I struggled with this myself.
I think you're on the right track, you just have a couple logic errors. I don't understand these two lines:
MCSession *session = [ArrayInvitationHandler objectAtIndex:0];
void (^invitationHandler)(BOOL, MCSession *) = [ArrayInvitationHandler objectAtIndex:0];
The object stored in your array is just your handler. The reason you're getting that crash is that the browser is seeing that accept
is true and trying to connect the peer to the session, but the session you're giving it back is nil. To fix this, you want to pass back a new session that you create.
At first I was confused by the notion of creating a new session when one has already been created by the browser side, but then I realized that we don't get that session from the browser anywhere, and we can't really pass it back into the invitation handler if it doesn't exist!
So yeah, do this instead:
BOOL accept = (buttonIndex != alertView.cancelButtonIndex) ? YES : NO;
// respond
MCSession *session;
if(accept) {
session = [[MCSession alloc] initWithPeer:peer];
session.delegate = self;
}
void (^invitationHandler)(BOOL, MCSession *) = [ArrayInvitationHandler objectAtIndex:0];
invitationHandler(accept, session);