我在tutorial(MCF)上关注此MultiPeerConnectivity并在线列出了大多数教程,他们采用了使用MCAdvertiserAssistant和MCBrowserViewController
服务的快捷方式我尝试使用MCNearbyServiceAdvertiser和MCNearbyServiceBrowser来实现相同的教程,因为我有兴趣在我的应用上自定义可发现性。
就列出附近的设备而言,情况正常。但是麻烦开始于MCNearbyServiceAdvertiserDelegate
,我称之为这种方法:
- (void) advertiser:(MCNearbyServiceAdvertiser *)advertiser
didReceiveInvitationFromPeer:(MCPeerID *)peerID
withContext:(NSData *)context
invitationHandler:(void (^)(BOOL, MCSession *))invitationHandler {
// Allow the peer to join this Vibereel
MCSession *peerSession = [[MCSession alloc] initWithPeer:_peerID];
peerSession.delegate = self;
invitationHandler(YES, peerSession);
NSLog(@"Accepted entry request for peer %@", [peerID displayName]);
}
不会触发did change state方法:
-(void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
虽然它与原始版本有关。
我知道我显然需要添加更多代码来演示问题..所以我创建了一个以原始代码开头的github repo。这是commit添加自定义浏览器以及自定义UITableViewController以显示附近的设备(工作正常),这是做广告的commit(不工作)
答案 0 :(得分:4)
使peerSession成为类的属性,而不是方法的局部变量。问题是在代码中,peerSession在方法结束时释放。我在blog上有一个有效的例子。
答案 1 :(得分:1)
在检查了您的回购代码之后,我想到了一些想法,我确定这个问题主要与您对MCSession
对象设置的方式有关。我同意Peter的观点,你应该在整个流程中有一个常见的会话对象作为强引用。
其次,因为你正试图让事情只用MCNearbyServiceBrowser
& MCNearbyServiceAdvertiser
,您需要确保一般正确设置流程。通过以下回调找到对等方后,
- (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info;
现在在对等端使用[browser invitePeer:peerID toSession:self.session withContext:nil timeout:0];
邀请对等方,您将收到以下代表的回调,
- (void) advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID
withContext:(NSData *)context
invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler
并且您通过向invitationHandler(YES, session)
确认接受邀请(正如您在上面所做的那样),如果您在整个流程中遇到了常见的会话对象,则- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
会触发MCSessionStateNotConnected
1}}然后MCSessionStateConnecting
状态。现在,在第一个对等体上,您将收到以下委托回调
- (void)session:(MCSession *)session
didReceiveCertificate:(NSArray *)certificate
fromPeer:(MCPeerID *)peerID
certificateHandler:(void(^)(BOOL accept))certificateHandler;
在这里你应该通过设置certificateHandler(YES)
来确认建立连接。这是最后一个非常重要的部分,特别是当你试图在没有工厂提供的视图控制器的情况下完成所有工作时。
我知道这不是第一次让它工作变得容易,但在此过程中它很容易实现。请在评论中提及我,我会回复您的任何澄清。