2014-09-20 1 views
4

Я после этого tutorial на MultiPeerConnectivity (MCF) и список большинство обучающих программ в Интернете, они взяли ярлык использования услуги MCAdvertiserAssistant и MCBrowserViewControllerПочему Мульти Connectivity Peer работает только с MCAdvertiserAssistant и не MCNearbyServiceAdvertiser

Я пытался, реализующим но с использованием 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

Можете ли вы отправить код, с которого вы отправляете приглашение? – ChrisH

+1

Я столкнулся с такой же проблемой и окончательно избавился от нее, удерживая сессию в переменной экземпляра. Его странный, но он сработал. –

ответ

4

Сделайте peerSession свойство класс вместо локальной переменной метода. Проблема в том, что в вашем коде peerSession выпущен в конце метода. У меня есть рабочий пример на моем blog.

+0

Экземпляр 'MCSession' передается в блок requestHandler, поэтому не имеет значения, что он выпущен в рамках метода. Я согласен, что сессия должна быть собственностью. Нет причин создавать новый каждый раз. – ChrisH

+0

Блог Питера также указывает на то, что с одноранговыми узлами, имеющими как рекламодателя, так и браузер, НЕ принимайте сеансы в обоих направлениях, или исходный код, похоже, запутывается. Он решил сравнить хэш из peerIDs в didReceiveInviation, чтобы решить, какой из двух должен принять и который должен отклонить. – mackworth

1

Несколько мыслей здесь после проверки кода на вашем репо, я уверен, что эта проблема в основном связана с тем, как у вас есть настройка объекта MCSession. Я согласен с Питером здесь, у вас должен быть один объект сеанса, общий для потока, как сильная ссылка.

Во-вторых, так как вы пытаетесь получить вещи работать только с 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, затем MCSessionStateConnecting. Теперь на первый пэра вы получите следующий делегат CallBack

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

и здесь вы должны быть подтверждением с помощью установки certificateHandler(YES) установить соединение. Это последний очень важный элемент, особенно когда вы пытаетесь заставить все это работать без установленных на заводе контроллеров представлений.

Я знаю, что это не просто заставить его работать в первый раз, но он становится легким на этом пути. Пожалуйста, упомяните меня в комментариях, я отвечу вам за любые разъяснения.