EASession,EAAccessoryDe​​legate和“ERROR - 开放会话失败”

时间:2010-12-09 02:22:05

标签: iphone bluetooth iphone-accessory

我正在使用External Accessory框架。我遇到问题在应用程序进入后台后重新建立EASession 然后返回到前台。如果我终止我的应用程序并重新启动,则会重新建立蓝牙连接,正如人们所期望的那样。我怀疑有一部分我正在丢失 - 或者没有曝光(??)。

[EAAccessoryManager sharedAccessoryManager] connectedAccessories]]正在返回我连接的附件,我可以查询它以获取name,modelNumber等。但是,以下行将_session设置为nil。

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

有没有办法诊断EASession初始化失败的原因?

是否有一些清除旧EASession的口头禅?

这个问题与this一个问题有关 - 但我并不是在寻求建议。我在问为什么这条路有这么大的陷阱以及如何在它周围导航。

5 个答案:

答案 0 :(得分:6)

我发现(在iOS4.1后的世界中)离开应用程序(后台或退出)会导致DidDisconnectNotification触发。在只是按下电源按钮或让设备睡眠的情况下;我们没有看到连接断开。

现在,如果BT设备超出范围或进入睡眠状态。然后连接断开。

因此,除了ConnectionNotifications之外,我们不再依赖任何东西。我们甚至不相信[[EAAccessoryManager sharedAccessoryManager] connectedAccessories]列表,因为我们发现它有时可以包含“鬼配件”,它们表示它们已连接并且具有可以连接到的流,并且即使在整个连接之后也可以从中获取可写事件蓝牙系统已经关闭(BT图标关闭)

当你在后台时缓存ConnectionNotifications,因此当你重新进入应用程序时,你应该得到一个新的状态。

当然首次进入;你想确保你已经正确地设置了所有听众(等)。

答案 1 :(得分:2)

据我所知,没有清除旧的EASession实例。我可以假设,但我不知道为什么会这样。我怀疑已建立的EASession不会释放与其附件的关联 - 这会阻止后续的EASession实例成功地与相同的附件相关联。

当应用程序重新启动时,我选择离开EASession。这似乎有效。在测试中,我已连接到蓝牙配件,启动我的应用程序,访问配件,将我的应用程序发送到后台,断开/重新连接BT配件,将应用程序带到前台并再次访问配件。这是我所希望的。

一个警告:使用iOS 4.0,可以有多个配件。例如,视频电缆和蓝牙设备都是配件。

答案 2 :(得分:2)

我遇到了同样的问题并用一个小技巧解决了它。我在打开会话时记录了附件的序列号,并在关闭会话时记录。

我看到一些会话未被关闭。因此,当我的应用程序进入后台模式时,我会按设备关闭所有已打开的会话。

-(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];
}

希望它可以帮助别人。

答案 3 :(得分:2)

我遇到了同样的问题。我正在开发一个应用程序,它会在一个定时间隔打开一个外部蓝牙附件,读取一些数据,然后关闭流。这已经好几天了,然后突然有一天它停止了解决这个问题。消息也记录在控制台中。

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,因为它已经好几天工作了。

我很困惑,我花了三天时间撞到了墙上。我搜索谷歌并最终在这里,我阅读了Apple的外部配件和NSStream编程指南沟通指南。代码都是正确的。

最后在第三天,我听到桌子角落发出一声哔哔声,我的Android手机已经没电了。一个灯泡在我脑海里消失了。我关掉手机和中提琴,iOS设备上的问题就消失了。

这确实是一个RF问题,而不是一个编程问题,但我在这里包含我的故事,如果其他人遇到这个问题,谷歌会把你带到这里。关闭附近的所有其他蓝牙无线电,因为它们是噪声源并可能导致此问题。

答案 4 :(得分:-1)

我正在解决同样的问题。在我的例子中,会话对象在创建之后具有retainCount = 3,因此在接收DidDisconnectNotification时,一个调用[session release]是不够的。确保在收到DidDisconnectNotification通知后确实释放了会话对象。