Multipeer Connectivity:接受邀请(使用内置浏览器VC)

时间:2013-09-26 00:03:26

标签: cocoa-touch ios7 invitation multipeer-connectivity

我正在尝试follow the WWDC talk来了解MultipeerConnectivity框架。经过许多错误的启动后,浏览器会显示同伴,并发出邀请。

但是当我在对等设备上按“接受”时,浏览器会一直显示“正在连接”。我认为MCBrowserViewController处理逻辑,我可以放松,直到浏览器的用户按下取消或完成,并且委托方法被触发。我敢打赌这是显而易见的,但它让我望而却步。

这是我希望的相关代码。我在AppDelegate中有它。各种委托方法中的NSLog语句按照我的预期被调用 - 当然除了browserViewControllerDidFinish:中的那个。

请记住,浏览器和邀请确实会出现,所以某些东西是对的!

在@interface ...

@property   (strong, nonatomic) MCSession   *theSession;
@property   (strong, nonatomic) MCAdvertiserAssistant       *assistant;
@property   (strong, nonatomic) MCBrowserViewController     *browserVC;

在@implementation

static    NSString* const    kServiceType = @"eeps-multi";

// called from viewDidAppear in the main ViewController

-(void)     startSession
{
    if (!self.theSession) {
        UIDevice *thisDevice = [UIDevice currentDevice];

        MCPeerID *aPeerID = [[ MCPeerID alloc ] initWithDisplayName: thisDevice.name];
        self.theSession = [[ MCSession alloc ] initWithPeer: aPeerID ];
        self.theSession.delegate = self;
    } else {
        NSLog(@"Session init skipped -- already exists");
    }
}

// called from viewDidAppear in the main ViewController

- (void)    startAdvertising
    {
    if (!self.assistant) {
        self.assistant = [[MCAdvertiserAssistant alloc] initWithServiceType:kServiceType
                                                              discoveryInfo:nil
                                                                    session:self.theSession ];
        self.assistant.delegate = self;
        [ self.assistant start ];
    } else {
        NSLog(@"Advertiser init skipped -- already exists");
    }
}

// called from the main ViewController in response to a button press

- (void)    startBrowsing
{
    if (!self.browserVC){
        self.browserVC = [[MCBrowserViewController alloc] initWithServiceType:kServiceType 
                                                                      session:self.theSession];
        self.browserVC.delegate = self;
    } else {
        NSLog(@"Browser VC init skipped -- already exists");
    }

    [ self.window.rootViewController presentViewController:self.browserVC animated:YES completion:nil];
}

提前致谢!

3 个答案:

答案 0 :(得分:15)

感谢评论者的出色建议,这让我发现了自己的错误。这是:

如果您实施MCSessionDelegate方法session:didReceiveCertificate:fromPeer:certificateHandler方法,它将拦截对等方连接到会话的尝试。您应该在该方法中明确批准该连接或将其注释掉。

详细信息和经验教训:

除了我展示的代码之外,我还对各种委托方法进行了粗短的实现。一个MCSessionDelegate方法是这个:

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

}

扩展@ Big-O Claire的建议,我开始观察所有这些委托方法,Just In Case。当对等人点击AdvertiserAssistant UI中的“接受”按钮时,会触发此消息。

如果你不愿意,这个方法让你有机会决定同伴是否合法而不是连接(使用certificateHandler:)。 Apple说,

  

您的应用应检查附近的同行证书,然后决定是否信任该证书。做出决定后,您的应用应该调用提供的certificateHandler块,传递YES(信任附近的对等方)或NO(拒绝它)。

另外,你得到这个提示:

  

重要:多重连接框架不会尝试以任何方式验证对等方提供的身份或证书。如果您的代理人没有实施此方法,则会自动接受所有证书。

当我评论这个方法时,连接经历了 - 至少这个问题已经解决了。

答案 1 :(得分:3)

我遇到了同样的问题,事实证明我正在为浏览器和广告客户使用相同的会话。拆分会话,但要确保serviceType相同,它就像魅力一样

- (void) setUpMultipeer{
    //  Setup Peer ID
    self.myPeerID = [[MCPeerID alloc] initWithDisplayName:[UIDevice currentDevice].name];

    //  Setup Sessions
    self.advertiseSession = [[MCSession alloc] initWithPeer:self.myPeerID];
    self.advertiseSession.delegate = self;

    self.browserSession = [[MCSession alloc] initWithPeer:self.myPeerID];
    self.browserSession.delegate = self;


    //  Setup BrowserVC
    self.browserVC = [[MCBrowserViewController alloc] initWithServiceType:@"SERVICE_TYPE" session:self.browserSession];
    self.browserVC.delegate = self;

    //  Setup Advertiser
    self.advertiser = [[MCAdvertiserAssistant alloc] initWithServiceType:@"SERVICE_TYPE" discoveryInfo:nil session:self.advertiseSession];
    [self.advertiser start];
}

答案 2 :(得分:1)

在使用新的MC框架时,我自己没有走过MCBrowserViewController路线,但是从WWDC演示文稿的幻灯片51看,browserViewControllerDidFinish:看起来只在用户按下时调用完成。因此,如果您的同伴仍然显示为“正在连接......”,则此回调可能不是问题所在。

我想知道您是否必须手动将对等方连接到会话。您已经设置了MCSession委托,因此我假设您正在实施session:peer:didChangeState。设置断点并注意MCSessionStateMCSessionStateConnected的时间。我唯一不确定的是,您是否需要在广告客户端,浏览器端或两者上手动处理此问题。如果你能弄清楚框架在哪一步停止处理它,那将会有所帮助。