iOS Multipeer连接框架invitationHandler似乎不接受?
我第一次使用mutlipeer连接框架,我想编程(而不是助理类)控制。
当我在两个单独的设备上运行我的代码,直到“广告客户”收到委托callback的时候,所有内容都按照上述说明进行操作:
浏览客户端的代理callback在发现广告商时被调用:
-(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];
}
然后广告客户端的代表callback在接收到邀请时被调用:
-(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's 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]; }
在“inviteHandler(YES,_session)”被调用之后,“浏览”客户端和“广告”客户端之间似乎没有build立连接。
我从来没有收到任何客户端设备上的MCSession对象的任何代理callback(一次或两次,我收到MCSessionStateNotConnected)。 我原以为我会收到MCSession委托callback:
-(void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state;
我错过了什么吗? 有没有其他人遇到过这个问题?
有一个苹果明显知道的错误。
这是导致发现的原因: 为什么我的MCSession同伴随机断开连接?
即使它在文档中列为可选,也必须实现以下代理callback…
- (void) session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL accept))certificateHandler { certificateHandler(YES); }
“didReceiveCertificate”委托方法是可选的,如果你不实现它,框架将假定你接受证书(注意证书可以是零)。
然而,如果你实现了这个方法,然后把它留空,那么当然,这个peer不会连接,因为这个框架会期望你用YES或者NO来调用certificateHandler。
我一直有类似的问题。 似乎如果我已经在一台iOS设备上运行我的应用程序,并连接到另一台,然后退出并重新启动(比如说,当我从Xcode重新运行时),那么我处于一种情况,在这种情况下,我得到一个Connected消息,然后是一个Not Connected稍后留言。 这是把我扔掉。 但仔细观察,我可以看到“未连接”消息实际上是指与已连接的不同peerId。
我认为这里的问题是,我所看到的大多数示例只关心peerID的displayName,忽略了可以为同一个device / displayName获取多个peerID的事实。
我现在先检查displayName,然后通过比较指针来validationpeerID是否相同。
- (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; ...
我发现的另一个问题(也在其他示例代码,即PeerKit中)是在inviteHandler(YES)之后的stopAdvertisingPeer可能是错误的。 因为即使你接受邀请,也不能保证你会被连接。 我认为只有在连接时才停止广告附件。