EASession, EAAccessoryDelegate и «ОШИБКА - сбой открытия сеанса» - PullRequest
7 голосов
/ 09 декабря 2010

Я работаю с платформой External Accessory. У меня возникают проблемы с восстановлением EASession после того, как приложение переходит в фоновый режим, а затем возвращается на передний план. Если я завершу свое приложение и перезапущу, то соединение Bluetooth будет восстановлено, как и следовало ожидать. Я подозреваю, что есть какая-то часть демонтажа, которую я пропускаю - или которая не разоблачена (??).

[EAAccessoryManager sharedAccessoryManager] connectedAccessories]] возвращает подключенный аксессуар, и я могу запросить его, чтобы получить имя, номер модели и т. Д. Однако в следующей строке для _session задано значение nil.

_session = [[EASession alloc] initWithAccessory:_accessory forProtocol:_protocolString];

Есть ли способ диагностики причины неудачной инициализации EASession?

Есть ли какая-то мантра для очистки старой EASession?

Этот вопрос относится к этому одному - но я не прошу совета, по какому пути идти. Я спрашиваю, почему этот путь имеет такую ​​большую ловушку и как пройти по нему.

Ответы [ 5 ]

6 голосов
/ 16 декабря 2010

Я обнаружил (в мире пост iOS4.1), что выход из приложения (фоновый режим или выход) вызовет отключение уведомления DidDisconnectNotification.В случае просто нажатия кнопки питания или отключения устройства;мы не видим, что соединение обрывается.

Теперь, если устройство BT выходит за пределы диапазона или само переходит в спящий режим.Затем соединение обрывается.

В результате мы больше не зависим ни от чего, кроме уведомлений о соединениях.Мы даже не доверяем списку [[EAAccessoryManager sharedAccessoryManager] connectedAccessories], потому что мы обнаружили, что он может иногда содержать «аксессуары-призраки», которые сообщают, что они подключены, и имеют потоки, к которым вы можете подключиться, и получать доступные для записи события даже после всей системы Bluetooth.отключился (значок BT выключен)

Уведомления о соединениях кэшируются, когда вы находитесь в фоновом режиме, поэтому вы должны получить новое состояние при повторном входе в приложение.

Конечно, при первом входе;Вы хотите убедиться, что вы правильно настроили всех слушателей (и т. д.).

2 голосов
/ 21 июня 2015

У меня была такая же проблема.Я разрабатывал приложение, которое бы открывал внешний Bluetooth-аксессуар через определенный промежуток времени, считывал некоторые данные, а затем закрывал потоки.Это работало нормально в течение нескольких дней, а затем однажды вдруг перестало работать именно с этой проблемой.Сообщение также было зарегистрировано на консоли.

2015-06-20 23:54:43.371 MyApp[2083:404019] ERROR - opening session failed
1 2015-06-20 23:54:43.371 MyApp[2083:404019] ERROR - /SourceCache/ExternalAccessory/ExternalAccessory-288.20.7/       EASession.m:-[EASession dealloc] - 141 unable to close session for _accessory=0x174018750 and sessionID=65536

Документация Apple ясна, только один экземпляр каждого протокола может быть открыт одновременно, и любой предыдущий экземпляр автоматически освобождается.Но почему вдруг iOS не смогла освободить предыдущую EASession, когда она работала хорошо в течение нескольких дней.

Я был озадачен и провел три дня, ударяя головой о стену.Я искал Google и попал сюда, я прочитал руководства Apple по общению с внешними аксессуарами и руководство по программированию NSStream.Код был верен.

Наконец, на третий день в углу моего стола послышался звуковой сигнал, в моем Android-телефоне кончился сок.У меня в голове погасла лампочка.Я выключил телефон и альт, проблема на устройстве iOS исчезла.

Это действительно проблема с радиочастотами, а не проблема программирования, но я привожу здесь свою историю, если кто-нибудь еще столкнется с этой проблемой, Googleприведет тебя сюда.Выключите все другие радиомодули Bluetooth в непосредственной близости, поскольку они являются источниками шума и могут привести к этой проблеме.

2 голосов
/ 06 мая 2014

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

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

-(void) closeSessionForDevice:(EAAccessory*) device{
EASession *lclSession = (EASession*) [sessionDictionary valueForKey:[device serialNumber]];
[[lclSession inputStream] close];
[[lclSession inputStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[lclSession inputStream] setDelegate:nil];

[[lclSession outputStream] close];
[[lclSession outputStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[lclSession outputStream] setDelegate:nil];

lclSession = nil;

NSLog(@"Session Closed for : %@", [device serialNumber]);

[device setDelegate:nil];
}

Надеюсь, это кому-нибудь еще поможет.

2 голосов
/ 14 декабря 2010

Насколько я могу судить, нет очистки старых экземпляров EASession. Я могу предположить, но я действительно не знаю, почему это так. Я подозреваю, что установленная EASession не освобождает свою связь со своим аксессуаром - и это препятствует успешному ассоциированию последующих экземпляров EASession с тем же аксессуаром.

Я решил оставить EASession в такте, когда приложение уходит в отставку. Кажется, это работает. В ходе тестирования я подключился к аксессуару Bluetooth, запустил свое приложение, получил доступ к аксессуару, отправил свое приложение в фоновый режим, отключил / повторно подключил аксессуар BT, вывел приложение на передний план и смог снова получить доступ к аксессуару. Это то, на что я мог надеяться.

Одно предостережение: с iOS 4.0 возможно иметь более одного аксессуара. Например, видеокабель и устройство Bluetooth являются аксессуарами.

0 голосов
/ 15 января 2011

У меня была та же проблема. В моем случае объект сеанса сразу после создания имеет retainCount = 3, поэтому при получении DidDisconnectNotification было недостаточно одного вызова [release session]. Убедитесь, что вы действительно освободили объект сеанса после получения уведомления DidDisconnectNotification.

...