iOS Multipeer Connectivity问题......
如果 MCNearbyServiceAdvertiser 拒绝来自 MCNearbyServiceBrowser 的邀请,请致电:
invitationHandler(NO, nil);
...中:
advertiser:didReceiveInvitationFromPeer:withContext:invitationHandler:
... MCNearbyServiceBrowser
是否有办法知道邀请是专门 已拒绝 ?
我确实看到使用MCNearbyServiceBrowser
的设备在广告客户拒绝邀请时收到会话状态更改为MCSessionStateNotConnected
,但我认为浏览设备可能会收到MCSessionStateNotConnected
其他人理由也是......就像广告商设备消失(关闭等)。
有关如何区分拒绝邀请与其他类型断开连接的任何建议?
谢谢。
-Allan
答案 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
应该被用作真正的同伴集合。