【问题标题】:iOS Multipeer connectivity framework invitationHandler doesn't seem to accept?iOS Multipeer 连接框架invitationHandler 似乎不接受?
【发布时间】:2014-02-11 09:53:55
【问题描述】:

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

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

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

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

}

然后广告客户端收到邀请后调用delegate回调:

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

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

【问题讨论】:

  • 您是否尝试过让浏览器和广告客户保持运行而不是立即停止?
  • 是的。不幸的是仍然有同样的行为。

标签: ios objective-c delegates multipeer-connectivity


【解决方案1】:

Apple 显然意识到了一个错误。

这就是导致发现的原因:Why does my MCSession peer disconnect randomly?

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

- (void) session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL accept))certificateHandler
{
 certificateHandler(YES);
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我也遇到过类似的问题。似乎如果我在一台 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;
      
      ...
      

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-02-23
          • 1970-01-01
          • 2012-09-21
          • 2021-09-09
          • 2017-12-16
          • 2011-05-21
          • 2016-04-10
          • 1970-01-01
          相关资源
          最近更新 更多