邀请Peer参加MCSEssion

时间:2015-10-09 19:18:02

标签: multipeer-connectivity mcsession

这是我第一次在stackoverflow上发帖,我知道严格的发布要求。如果我没有遵循任何指导原则,请告诉我。

我目前正在使用Objective-C在Xcode中编写IOS(8.4)应用程序。目标是使用MCSessions在IOS设备之间传输数据。尽管我在这里和其他地方阅读了许多试图澄清主题的帖子,但我目前正在努力解决会话的问题。以下是我已经了解的资源:

https://developer.apple.com/videos/play/wwdc2013-708/

https://medium.com/@phoenixy/using-multipeer-connectivity-120abacb9db

以下是我目前的理解:在最基本的层面上,您有广告客户和浏览器。广告商有一个本地会话,允许他们“做广告”。当浏览器看到广告商时,浏览器向广告商发送邀请给他(浏览器的)本地MCSession。假设这一切都是正确的,这就是我感到困惑的地方。广告客户可以接受邀请,并在此过程中将其本地会话传递给invitationHandler。

我在代码中实现了以下逻辑,如下所示。但是,在跟踪广告商和浏览器的MCSession状态更改时,会尝试连接,但最终状态始终为didNotNonnect。

发送邀请的代码(浏览器):

[self.broadcasterBrowser invitePeer:[broadcasterPeerIDs objectAtIndex:indexPath.row]
        toSession: self.appDelegate.mpcHandler.session withContext:nil timeout:30.0 ];

接受邀请的代码(广告商):

       - (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser 
didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler
    {
        ArrayInvitationHandler = [NSArray arrayWithObject:[invitationHandler copy]];

        // ask the user
        UIAlertView *alertView = [[UIAlertView alloc]
                                  initWithTitle:peerID.displayName
                                  message:@"Would like to create a session with you"
                                  delegate:self
                                  cancelButtonTitle:@"Decline"
                                  otherButtonTitles:@"Accept", nil];
        [alertView show];

        if (alertViewResult)
        {
            void (^invitationHandler)(BOOL, MCSession *) = [ArrayInvitationHandler objectAtIndex:0];
            invitationHandler(YES, self.appDelegate.mpcHandler.session);


        }
    }

非常感谢任何帮助!

奥斯汀

1 个答案:

答案 0 :(得分:0)

我在试图使用MPC时遇到了类似的问题。我创建了一个自定义类来处理所有MPC连接细节。虽然在测试时,每次我的广告客户都接受邀请时,它会抱怨错误的连接数据并失败。我发现问题是我从我创建的类变量中删除了我的设备的MCPeerID对象,如下所示:

 static var peerObject : MCPeerID {
    return MCPeerID(displayName: deviceNameString)
 }

 lazy var sessionIVar = MCSession (peer: MyConnectivityClass.peerObject)

 func startAdvertisingForConnectivity () {
    advertiserService = MCNearbyServiceAdvertiser (peer: MyConnectivityClass.peerObject, discoveryInfo: nil, serviceType: "my-multipeer-connectivity-service-identifier")
 }

然后当我收到邀请时,我会使用“peerObject”计算属性初始化一个MCSession对象并将其返回到邀请处理程序中,如下所示:

 func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Swift.Void) {
    invitationHandler(true, sessionIVar)
 }

我假设每次调用“MyConnectivityClass.peerObject”时它会返回一个相同的peerID,因为我总是使用相同的显示名称初始化它。事实证明这不是真的。因此,当我在做广告时,我正在使用一个peerID对象,然后当我响应邀请时,我正在使用包含完全不同的peerID的MCSession对象进行响应。

因此,解决方案是将“MyConnectivityClass.peerObject”计算类属性更改为连接处理程序类中的常量或Ivar。像这样:

 let peerObject : MCPeerID = MCPeerID(displayName: deviceNameString)

然后剩下的代码才起作用,因为无论我多少次调用MCPeerID对象,它总是一样的。回想起来,我不知道为什么我开始按照我的方式开始。 :-)

然后在我的连接类中,我为浏览器和广告商存档并存储了MCPeerID对象,这样我就可以让广告商自动接受受信任的MCPeerID的邀请。如果您每次使用它时都创建MCPeerID对象,那是不可能的,即使您始终使用相同的DisplayName对其进行初始化。

相关问题