Multipeer Connectivity: получение приглашения принято (с помощью встроенного в браузер VC)

Я пытаюсь следить за докладом WWDC, чтобы узнать о структуре 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 ответа

Решение

Спасибо комментаторам за прекрасные предложения, которые привели к тому, что я нашел свою ошибку. И вот оно:

Если вы реализуете 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.

Этот метод дает вам возможность решить, является ли одноранговый узел законным и не подключен (используя certificateHandler:) если не хочешь. Apple говорит,

Ваше приложение должно проверить сертификат соседнего партнера, а затем решить, доверять ли этому сертификату. После этого определения ваше приложение должно вызвать предоставленный блок certificateHandler, передавая либо YES (чтобы доверять соседнему узлу), либо NO (чтобы отклонить его).

Кроме того, вы получите этот совет:

Важное замечание: Структура многопользовательского подключения не предпринимает никаких попыток проверить предоставленные одноранговым узлом удостоверения или сертификаты каким-либо образом. Если ваш делегат не реализует этот метод, все сертификаты принимаются автоматически.

Когда я прокомментировал этот метод, соединения прошли - и ЭТА проблема, по крайней мере, была решена.

У меня была та же проблема, и оказалось, что я использую один и тот же сеанс как для браузера, так и для рекламодателя. разделите сессии, но убедитесь, что 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];
}

Я не ушел MCBrowserViewController при работе с новой платформой MC, но из слайда 51 презентации WWDC это выглядит как browserViewControllerDidFinish: вызывается только тогда, когда пользователь нажимает "Готово". Таким образом, этот обратный вызов, вероятно, не в том, в чем проблема, если ваш партнер по-прежнему отображается как "Соединение...".

Мне интересно, если вы должны подключить своих коллег к сеансу вручную. Вы уже устанавливаете MCSession делегат, так что я предполагаю, что вы реализуете session:peer:didChangeState, Установите точку останова и следите за тем, когда MCSessionState является MCSessionStateConnected, Единственное, в чем я не уверен - это если вам нужно вручную обработать это на стороне рекламодателя, на стороне браузера или на обеих сторонах. Если бы вы могли выяснить, на каком этапе фреймворк перестает с ним работать, это было бы полезно.

Другие вопросы по тегам