iOS Multipeer连接框架invitationHandler似乎不接受?

时间:2014-01-21 16:54:01

标签: ios objective-c delegates multipeer-connectivity

我第一次使用mutlipeer连接框架,我想要编程(而不是助手类)控制。

当我在两个单独的设备上运行我的代码时,一切都正常工作,直到'广告客户'收到委托回调为止:

浏览客户端的委托回调在发现广告商时被调用:

-(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];

}

然后,广告客户端的委托回调在收到邀请时被调用:

-(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];
}

在调用'invitationHandler(YES,_session)'之后,似乎永远不会在'浏览'客户端和'广告'客户端之间建立连接。

我在任一客户端设备上的MCSession对象上都没有收到任何委托回调(我收到一次或两次MCSessionStateNotConnected)。我原本以为我会收到MCSession委托回调:

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

我错过了什么吗?还有其他人遇到过这个问题吗?

4 个答案:

答案 0 :(得分:9)

Apple显然有一个错误。

这导致了这一发现:Why does my MCSession peer disconnect randomly?

您必须实现以下委托回调,即使它在docs ...

中列为可选项
- (void) session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL accept))certificateHandler
{
 certificateHandler(YES);
}

答案 1 :(得分:1)

" didReceiveCertificate"委托方法是可选的,如果你不实现它,框架将假定你接受证书(注意证书可以是零)。

但是,如果您实现该方法然后将其保留为空,那么,确定,对等方将无法连接,因为框架将期望您使用YES或NO调用certificateHandler。

答案 2 :(得分:1)

我一直有类似的问题。看来,如果我在一台iOS设备上运行我的应用程序,并连接到另一台设备,然后退出并重新启动(比如当我从Xcode重新运行时),那么我处于一种情况下,我收到一条已连接的消息,然后是一台未连接的消息稍后。这让我失望了。但仔细观察,我可以看到Not Connected消息实际上是针对与已连接的消息不同的peerId。

我认为这里的问题是我见过的大多数样本只关心peerID的displayName,而忽略了你可以为同一个device / displayName获得多个peerID的事实。

我现在首先检查displayName,然后通过比较指针来验证peerID是否相同。

- (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;

...

答案 3 :(得分:0)

我发现的另一个问题(也在其他示例代码中,即PeerKit)是在InvitationHandler(YES)之后的stopAdvertisingPeer可能是错误的。因为即使您接受邀请,也无法保证您将被连接。我认为最好只在连接时停止广告节目。