I'm working on an iOS app communicate with Bluetooth 2.1. App connects to BT when it becomes active. It works fine if app goes to background and becomes active again.
But I just noticed a problem:
If I turn BT module power off, app get a notification where I do the following:
- (void)accessoryDidDisconnect:(EAAccessory *)accessory
{
NSLog(@"EAController::accessoryDidDisconnect:");
_selectedAccessory = nil;
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Alert" message:@"Lost connection. " delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:YES forKey:@"Lost Communication"];
[self closeSession];
}
Then I turn the module power back on, go to Settings -> Bluetooth, connect BT module to iPhone, active app (come back from background), EASession can not be initiated:
if (_session == nil)
{
NSLog(@"EAController::openSession");
[_selectedAccessory setDelegate:self];
_session = [[EASession alloc] initWithAccessory:[self selectedAccessory] forProtocol:_protocolString];
if (_session)
{
// Set up delegate........
}
else
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:NO forKey:Unit_Has_Connection_UserDefault_Key];
NSLog(@"creating session failed");
}
}
Initiate _accessoryList and _selectedAccessory:
_accessoryList = [[NSMutableArray alloc] initWithArray:[[EAAccessoryManager sharedAccessoryManager] connectedAccessories]];
_selectedAccessory = [_accessoryList objectAtIndex:0];
I found out _accessoryList has the accessory I'm using but it's "Protocols" is empty.
$12 = 0x1dd58050 <__NSArrayI 0x1dd58050>(
<EAAccessory: 0x1dd1dce0> {
connected:YES
connectionID:XXX
name: XXX
manufacturer: XXX
modelNumber: XXX
serialNumber:
firmwareRevision: XXX
hardwareRevision: XXX
macAddress: XXX
protocols: (
)
delegate: (null)
}
)
If I kill the app and restart, it works fine.
Does anyone know how to solve this?
This question is similar to this one , but happens in different situations and the answer to that question doesn't seem to solve my problem.
After days of searching for solution, I finally solved this problem(Or I hope I solved it.). I'm posting my answer here so if anyone has the same problem can have an idea.
You can never trust EAAccessoryManager, it may have ghost accessory. So initiate _accessoryList using the following command doesn't always work.
If you initiate an accessoryList with a ghost accessory, for sure you cannot successfully initiate an EASession.
The right way is to use EAAccessory Notification, which described in this answer, but it didn't say how to do it in detail.
First, you need to create post two notifications:
Then in accessoryConnected and accessoryDisconnected, you can do the following.