MCNearbyServiceBrowser如何知道MCNearbyServiceAdvertiser是否拒绝了邀请?

时间:2014-06-29 08:38:32

标签: ios ios7 multipeer-connectivity

iOS Multipeer Connectivity问题......

如果 MCNearbyServiceAdvertiser 拒绝来自 MCNearbyServiceBrowser 的邀请,请致电:

invitationHandler(NO, nil);

...中:

advertiser:didReceiveInvitationFromPeer:withContext:invitationHandler:

... MCNearbyServiceBrowser是否有办法知道邀请是专门 已拒绝

我确实看到使用MCNearbyServiceBrowser的设备在广告客户拒绝邀请时收到会话状态更改为MCSessionStateNotConnected,但我认为浏览设备可能会收到MCSessionStateNotConnected其他人理由也是......就像广告商设备消失(关闭等)。

有关如何区分拒绝邀请与其他类型断开连接的任何建议?

谢谢。

-Allan

1 个答案:

答案 0 :(得分:5)

根据文档,MCSessionStateNotConnected可以表示

  

“......附近的同伴拒绝了邀请,连接无法联系   建立,或先前连接的同伴不再连接。“

您没有在问题中说明会导致拒绝邀请的原因,但假设它是由用户驱动的,一种方法可能是让您的MCNearbyServiceAdvertiserDelegate自动接受邀请,为每个邀请创建一个新会话peer,然后向用户呈现接受或拒绝连接的选择。在他们收到指示用户决定的后续消息之前,您的同行不会被视为真正的对话:

因此,在您的MCNearbyServiceAdvertiserDelegate课程中,您接受并提示用户:

- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser
didReceiveInvitationFromPeer:(MCPeerID *)peerID
                 withContext:(NSData *)context
           invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler {

          //Automatically accept with a new session
          MCSession *newSession = [[MCSession alloc] initWithPeer:_myPeerID];
          newSession.delegate = self;

          //Keep track of the pending sessions in a mutable dictionary
          _pendingSessionPeerIDMap[peerID.displayName] = newSession;

          invitationHandler(YES,newSession);

          /* Code here to present user with option to accept or decline peer */
}

然后,当用户响应时,您可以使用一个方法将一个简单的字符串作为NSData包含状态:

@property NSData *inviteAcceptedMsgData = [@"MPCInviteYES" dataUsingEncoding:NSUTF8StringEncoding];
@property NSData *inviteDeclinedMsgData = [@"MPCInviteNO" dataUsingEncoding:NSUTF8StringEncoding];

- (void)invitationFromPeerID:(MCPeerID *)peerID receivedResponse:(BOOL)accepted {

   //Send a message to the peer that sent the invitation indicating whether the
   //user accepted or declined

   NSData *msgData = (accepted) ? _inviteAcceptedMsgData : _inviteDeclinedMsgData;

   MCSession *peerSession = _pendingSessionPeerIDMap[peerID.displayName];

   [peerSession sendData:msgData
                 toPeers:@[peerID]
                withMode:MCSessionSendDataReliable
                   error:nil];

    //Remove the pending session
    [_pendingSessionPeerIDMap removeObjectForKey:peerID.displayName];

    //And if the connection was accepted by the user, add to an accepted dictionary
    _acceptedSessionPeerIDMap[peerID.displayName] = peerSession;
}

MCNearbyServiceBrowserDelegate的工作方式类似:

- (void)browser:(MCNearbyServiceBrowser *)browser 
      foundPeer:(MCPeerID *)peerID 
withDiscoveryInfo:(NSDictionary *)info {

    //Send the invitation with a new session
    MCSession *newSession = [[MCSession alloc] initWithPeer:_myPeerID];
    newSession.delegate = self;

    [browser invitePeer:peerID
              toSession:newSession
            withContext:nil
                timeOut:0];
}

然后,浏览器会等待来自其邀请的对等方的消息,以确定是否真的接受了邀请:

- (void)session:(MCSession *)session 
 didReceiveData:(NSData *)data 
       fromPeer:(MCPeerID *)peerID {

       //Check the data to see whether invite was accepted
       if ([data isEqualToData:_inviteAcceptedMsgData]) {

            //Add to an accepted dictionary
            _acceptedSessionPeerIDMap[peerID.displayName] = session;
       }
       else if ([data isEqualToData:_inviteAcceptedMsgData]){

            //Disconnect the session
            [session disconnect];
       }
}

您可能已经有一个消息传递系统,但这代表了在连接的对等体之间传递状态的简单实现。就发送广播或显示连接的对等体而言,_acceptedSessionPeerIDMap应该被用作真正的同伴集合。