Multipeer Connectivity: просмотр в Objective-C ++ тихо завершается неудачей - PullRequest
0 голосов
/ 15 апреля 2019

Я пытаюсь написать сторону браузера / обнаружения для приложения Multipeer Connectivity в Objective-C ++.Я думаю, что могу рекламировать, насколько я могу сказать в любом случае, так как я вижу это с помощью Discovery (https://itunes.apple.com/us/app/discovery-dns-sd-browser/id1381004916?mt=12). Но мой браузер ничего не видит. Что я делаю не так?

#include <iostream>
#include <thread>

#import <MultipeerConnectivity/MultipeerConnectivity.h>

@interface Bowser : NSObject<MCNearbyServiceBrowserDelegate>

- (void)browser:(MCNearbyServiceBrowser *)browser 
    foundPeer:(MCPeerID *)peerID 
    withDiscoveryInfo:(NSDictionary *)info;

- (void)browser:(MCNearbyServiceBrowser *)browser 
    lostPeer:(MCPeerID *)peerID;

@end

@implementation Bowser

- (void)browser:(MCNearbyServiceBrowser *)browser 
    foundPeer:(MCPeerID *)peerID 
    withDiscoveryInfo:(NSDictionary *)info {
    std::cout << "Hello" << std::endl;
}

- (void)browser:(MCNearbyServiceBrowser *)browser 
    lostPeer:(MCPeerID *)peerID {
    std::cout << "Goodbye" << std::endl;
}

@end

int main() {
    MCPeerID* peerid = [[MCPeerID alloc] initWithDisplayName:@"PeerId"];
    Bowser* delegate = [[Bowser alloc] init];

    MCNearbyServiceBrowser* browser = [MCNearbyServiceBrowser alloc];
    [browser initWithPeer:peerid serviceType:@"m"];

    browser.delegate = delegate;

    [browser startBrowsingForPeers];

    using namespace std::chrono_literals;
    std::this_thread::sleep_for(10s);

    [browser stopBrowsingForPeers];
}

Также были бы полезны предложения о том, как отладить происходящее. Кто-нибудь ...?

1 Ответ

0 голосов
/ 16 апреля 2019

Я (наконец) понял это. MultipeerConnectivity нужен цикл выполнения. Это не в документации.

Я предположил, что API MultipeerConnectivity создал потоки и / или циклы, необходимые для вызова метода [browser startBrowsingForPeers]. Это не так.

Нигде в этом коде не запущен цикл выполнения. Также, что довольно интересно, использование NSThread напрямую не запускает цикл выполнения, хотя подразумевает, что он будет :

Ваше приложение не создает и не управляет NSRunLoop явным образом объекты. Каждый объект NSThread, включая основной поток - имеет объект NSRunLoop, автоматически создаваемый для него по мере необходимости. Если вам нужен доступ к циклу выполнения текущего потока, вы делаете это с помощью метод класса currentRunLoop.

Что создаст цикл выполнения (и запустит его): CFRunLoopRun():

Цикл выполнения текущего потока выполняется в режиме по умолчанию (см. Default Run Loop Mode), пока цикл выполнения не будет остановлен с помощью CFRunLoopStop или всех источники и таймеры удалены из режима цикла выполнения по умолчанию.

Что остановит это, то это CFRunLoopStop(CFRunLoopRef rl):

Эта функция заставляет rl прекратить работу и вернуть управление функция, которая называется CFRunLoopRun или CFRunLoopRunInMode для Активация токовой петли.

Конечно, CFRunLoopStop принимает CFRunLoopRef в качестве аргумента. Вы можете получить это, используя CFRunLoopGetCurrent, просто помните, что это ссылка и срок ее действия может истечь в любое время. Я думаю, вы можете быть уверены, что цикл выполнения не прекратится, пока вы находитесь в обратном вызове, который выполняется в цикле выполнения. Но я бы не стал рассчитывать на то, что оно останется после. На самом деле, в этом случае, весь смысл в том, чтобы убить его на этом этапе; так что я ожидаю, что это уйдет.

...