9

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

当我在两个单独的设备上运行我的代码直到“广告商”收到委托回调时,一切都按照描述的方式工作:

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

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

4 回答 4

11

苹果显然意识到了一个错误。

这就是导致发现的原因:为什么我的 MCSession 对等方会随机断开连接?

您必须实现以下委托回调,即使它在文档中列为可选...

- (void) session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL accept))certificateHandler
{
 certificateHandler(YES);
}
于 2014-01-22T11:15:17.053 回答
1

“didReceiveCertificate”委托方法是可选的,如果您不实现它,框架将假定您接受证书(请注意,证书可以为 nil)。

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

于 2014-06-05T22:15:06.700 回答
1

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

我认为这里的问题是我见过的大多数示例只关心 peerID 的 displayName,而忽略了您可以为同一设备/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;

...
于 2014-12-26T00:54:34.603 回答
0

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

于 2017-02-28T02:16:16.907 回答