2014-01-21 3 views
8

Я впервые использую инфраструктуру соединения mutlipeer, и я хочу, чтобы программный (не с помощниками классов) контроль.Интерфейс подключения IOS Multipeer приглашенияHandler, похоже, не принимает?

Все работает точно так, как описано, когда я запускаю мой код на два отдельных устройства вплоть до того момента, когда «рекламодатель» принимает делегат обратного вызова:

делегат обратного вызова Травоядные клиента вызывается, когда он обнаруживает, рекламодателю:

-(void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info{ 
    [[[UIAlertView alloc] initWithTitle:@"Peer Found" message:peerID.displayName delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] show]; 

    _session = [[MCSession alloc] initWithPeer:_myPeerID]; 
    _session.delegate = self; 

    //connect to the discovered peer. 
    [_browser invitePeer:peerID toSession:_session withContext:nil timeout:30.0]; 
    [_browser stopBrowsingForPeers]; 

}

Затем делегат обратного вызова рекламного клиента вызывается, когда он получает приглашение:

-(void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void (^)(BOOL, MCSession *))invitationHandler{ 

    //when my code runs, everything looks correct here. 
    //eg. peerID is definitely my 'browser' client's display name etc. 

    _session = [[MCSession alloc] initWithPeer:_myPeerID]; 
    _session.delegate = self; 

    //using a simple version for testing... accept all invites. 
    invitationHandler(YES, _session); 

    //stop advertising now. 
    [_advertiser stopAdvertisingPeer]; 
} 

После вызова приглашения «Приглашение (YES, _session)» кажется, что соединение между клиентом просмотра и клиентом «рекламы» никогда не устанавливается.

Я не получаю никаких обратных вызовов делегатов (один или два раза я получил MCSessionStateNotConnected) на объектах MCSession на любом клиентском устройстве. Я бы подумал, что получил бы ответный вызов делегата MCSession:

-(void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state; 

Я что-то упустил? Кто-нибудь еще сталкивается с этой проблемой?

+0

Вы пробовали оставить браузера и рекламодателя, вместо того чтобы немедленно их остановить? – ChrisH

+0

Да. К сожалению, по-прежнему было такое же поведение. –

ответ

9

Существует ошибка, о которой Apple, очевидно, знает.

Это то, что привело к открытию: Why does my MCSession peer disconnect randomly?

Вы должны выполнить следующий делегат обратного вызова, даже если он указан как опция в документации ...

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

«didReceiveCertificate» метод делегата является необязательным, и если вы его не реализуете, структура предполагает, что вы принимаете сертификат (обратите внимание, что сертификат может быть равен нулю).

Однако, если вы реализуете метод, а затем оставьте его пустым, то, конечно, одноранговый узел не будет подключаться, потому что инфраструктура ожидает, что вы вызовете сертификатHandler с YES или NO.

1

У меня были подобные проблемы. Кажется, что если я запустил приложение на одном устройстве iOS и подключился к другому, то закройте и перезапустите (скажем, когда я перейду с Xcode), то я в ситуации, когда я получаю сообщение Connected, а затем не подключен сообщение немного позже. Это меня отбросило. Но, глядя более внимательно, я вижу, что сообщение Not Connected на самом деле предназначено для другого peerId, чем тот, который подключен.

Я думаю, проблема в том, что большинство образцов, которые я видел, просто заботятся о displayName peerID и пренебрегают тем фактом, что вы можете получить несколько peerID для одного и того же устройства/displayName.

Теперь я проверяю имя displayName, а затем проверяю, что peerID тот же, выполнив сравнение указателей.

- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state { 

    MyPlayer *player = _players[peerID.displayName]; 

    if ((state == MCSessionStateNotConnected) && 
     (peerID != player.peerID)) { 
     NSLog(@"remnant connection drop"); 
     return; // note that I don't care if player is nil, since I don't want to 
       // add a dictionary object for a Not Connecting peer. 
    } 
    if (player == nil) { 
     player = [MyPlayer init]; 
     player.peerID = peerID; 
     _players[peerID.displayName] = player; 
    } 
    player.state = state; 

... 
0

Другая проблема, которую я нашел (также в других примерах кодов, т.е.e PeerKit) заключается в том, что stopAdvertisingPeer сразу после приглашенияHandler (YES), вероятно, ошибочен. Потому что даже вы принимаете приглашение, нет никакой гарантии, что вы будете связаны. Я думаю, что лучше прекратить рекламироватьPeer только при подключении.

Смежные вопросы