Приглашение коллег на MCSEssion

Это моя первая публикация на stackoverflow, и я знаю о строгих требованиях к публикации. Пожалуйста, дайте мне знать, если я не соблюдаю какие-либо рекомендации.

В настоящее время я пишу приложение IOS (8.4) в Xcode, используя Objective-C. Цель состоит в том, чтобы использовать MCSessions для потоковой передачи данных между устройствами IOS. В настоящее время я борюсь с концепцией сеансов, несмотря на чтение многочисленных сообщений здесь и в других местах, которые пытаются прояснить тему. Вот ресурсы, о которых я уже знаю:

https://developer.apple.com/videos/play/wwdc2013-708/

https://medium.com/@phoenixy/using-multipeer-connectivity-120abacb9db

Вот мое текущее понимание: на самом базовом уровне у вас есть рекламодатель и браузер. У рекламодателя есть локальная сессия, которая позволяет ему «рекламировать». Когда браузер видит рекламодателя, он отправляет рекламодателю приглашение в его (браузера) локальную MCSession. Предполагая, что это все правильно, вот где я запутался. Рекламодатель может принять приглашение и в процессе передать свой локальный сеанс обработчику приглашений.

Я реализовал следующую логику в коде, как показано ниже. Однако при отслеживании изменений состояния MCSession как для рекламодателя, так и для браузера предпринимается попытка подключения, но конечное состояние всегда равно didNotNonnect.

Код для отправки приглашения (Браузер):

[self.broadcasterBrowser invitePeer:[broadcasterPeerIDs objectAtIndex:indexPath.row]
        toSession: self.appDelegate.mpcHandler.session withContext:nil timeout:30.0 ];

Код для принятия приглашения (Рекламодатель):

       - (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser 
didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler
    {
        ArrayInvitationHandler = [NSArray arrayWithObject:[invitationHandler copy]];

        // ask the user
        UIAlertView *alertView = [[UIAlertView alloc]
                                  initWithTitle:peerID.displayName
                                  message:@"Would like to create a session with you"
                                  delegate:self
                                  cancelButtonTitle:@"Decline"
                                  otherButtonTitles:@"Accept", nil];
        [alertView show];

        if (alertViewResult)
        {
            void (^invitationHandler)(BOOL, MCSession *) = [ArrayInvitationHandler objectAtIndex:0];
            invitationHandler(YES, self.appDelegate.mpcHandler.session);


        }
    }

Любая помощь приветствуется!

Остин


person Austin    schedule 09.10.2015    source источник


Ответы (1)


Я столкнулся с похожей проблемой, пытаясь использовать MPC. Я создал собственный класс для обработки всех деталей подключения MPC. Однако во время тестирования каждый раз, когда мой рекламодатель принимал приглашение, он жаловался на неправильные данные подключения и терпел неудачу. Я обнаружил, что проблема заключалась в том, что я продавал объект MCPeerID для своего устройства из переменной класса, которую я создал, как показано ниже:

 static var peerObject : MCPeerID {
    return MCPeerID(displayName: deviceNameString)
 }

 lazy var sessionIVar = MCSession (peer: MyConnectivityClass.peerObject)

 func startAdvertisingForConnectivity () {
    advertiserService = MCNearbyServiceAdvertiser (peer: MyConnectivityClass.peerObject, discoveryInfo: nil, serviceType: "my-multipeer-connectivity-service-identifier")
 }

Затем, когда я получил приглашение, я инициализировал объект MCSession, используя вычисляемое свойство «peerObject», и возвращал его в обработчик приглашения, например:

 func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Swift.Void) {
    invitationHandler(true, sessionIVar)
 }

Я предполагал, что каждый раз, когда я вызываю "MyConnectivityClass.peerObject", он будет возвращать идентичный идентификатор узла, потому что я всегда инициализировал его с одним и тем же отображаемым именем. Оказывается, это неправда. Поэтому, когда я рекламировал, я использовал один объект peerID, а затем, когда я отвечал на приглашение, я отвечал объектом MCSession, который содержал совершенно другой peerID.

Таким образом, решение состояло в том, чтобы изменить свойство вычисляемого класса MyConnectivityClass.peerObject на константу или Ivar в моем классе обработчика соединений. Так:

 let peerObject : MCPeerID = MCPeerID(displayName: deviceNameString)

Затем остальная часть кода просто работала, потому что независимо от того, сколько раз я вызывал объект MCPeerID, он всегда был одним и тем же. Оглядываясь назад, я не знаю, почему я начал именно с этого. :-)

Затем в своем классе подключения я заархивировал и сохранил объекты MCPeerID как для браузера, так и для рекламодателя, чтобы рекламодатель мог автоматически принимать приглашение для доверенных идентификаторов MCPeerID. Это невозможно, если вы создаете объект MCPeerID каждый раз, когда используете его, даже если вы всегда инициализируете его одним и тем же DisplayName.

person bdepaz    schedule 21.09.2016