OBJ-C Practical Guide: An Application Using BLE and iBeacon Connection on the Same Device

I have a use case when my objective-c application needs to use iBeacon immediately after it is completed in order to wake the application from its completed state, connect to BLE and send a command to the device. I have a longer working mail found here , which you can check for my code if necessary.

Problem

The problem still arises when starting the application, searching for previously paired devices and / or scanning peripheral devices, searching for a BLE device and connecting. Once connected, the user connects the BLE connection so that they can send encrypted feature data through the BLE connection. Without pairing (aka auth / bond in device naming conventions), the user cannot send data to the device at all. It never happens. Once you connect, you can send a command ...

When I complete the application, in the applicationWillTerminate method, I run this code ...

 - (void)applicationWillTerminate:(UIApplication *)application { NSLog(@"*** Application Will Terminate."); NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSNumber *mode = [userDefaults objectForKey:@"deviceConnectedMode"]; if([mode intValue] == CONNECTED_MODE_INDICATOR) { [self.bluetoothManager sendCodeToBTDevice:@"magiccommand1" characteristic:self.bluetoothManager.wipeCharacteristic]; //I have been turning this command on and off in testing to see if I can get it to work better while disconnecting in the device rather than in the app... //The command magiccommand2 wipes the auth/bond inside of the device // [self.bluetoothManager sendCodeToBTDevice:@"magiccommand2" // characteristic:self.bluetoothManager.disconnectCharacteristic]; //Place where I attempt to stop being connected to BT [self.bluetoothManager disconnectDevice]; [self.beaconManager startMonitoring]; NSLog(@"*** Application terminated from connected mode!"); } else { NSLog(@"*** DriveCare terminated without violation!"); } } 

What am i trying to accomplish

The magiccommand1 and magiccommand2 are just stupid test strings (currently 128 bit tokens) that the device listens through the serial port. As soon as they receive the commands that they respond, trying to erase auth / bond on the device, as well as disconnect from the BLE in the device.

Thus, the only way to make the application wake up with a completed state is iBeacon. So I need to make a bunch of seemingly dirty stuff here to get this round peg in a square hole. In the application life cycle, it connects and connects, and when I finish, I want it to be completely removed as a connected device from BLE. I hope iBeacon wakes up the application, connects to BLE, disables iBeacon monitoring, and then sends a command to the BLE device from the exit state. This on / off or connection / disconnection from iBeacon to BLE and vice versa is likely to cause the need for a second pair, and I do not want this.

Additional issues

When I call [self.centralManager cancelPeripheralConnection:self.thePeripheral]; , BT manager at the iOS system level automatically connects almost instantly (due to pairing), so there is no time to disconnect the connection, and iBeacon will be raised again. If I try to disconnect from the centralManager instance before sending the disconnect command to my field (as seen above in the code commented out), they obviously will not send. If I just use only this CBCentralManager disconnect method, this is not enough for iBeonon, since the iOS system is still paired with the device. Finally, if I then went into my BT system manager on iOS and select “Forget this device”, iBeacon will reappear and my didEnterRegion method didEnterRegion work!

It's a lot back and forth between iBeacon and BLE, and I'm just sorry that I don't need iBeacon to wake the application. I have all the info.plist BLE functions and iBeacon services. If I don’t connect to BLE at all and never connect once and connect my device, notifications about the local application without problems tell me that the iBeacon didEnterRegion and didExitRegion run without problems.

What am I doing wrong here?

+5
source share
1 answer

I understood this answer! I was on the right track ... Do not try to disconnect from the BT pair to try to run the iBeacon delegation methods. This causes a lot of weird dirty code, closely related things that shouldn't be worse ... scary spaghetti code.

Instead, I decided to build a board with two Bluetooth chips. One as a dedicated iBeacon chip, and the other as a permanently connected / paired / authenticated chip. Thus, to monitor (or, even worse) race conditions, no temporary connection and disconnection events are required. Waiting for a device to turn off in iOS is not a true disconnect, instead, when the iOS system considers it to be disabled (on the phone). What is happening inside the peripheral system paints a completely different picture ...

This 2-dimensional approach has made life a lot easier on the development side, because now that you need the application to wake up to process something, you can use the iBeacon device and get the corresponding event.

Side note: When using iBeacon, the didEnterRegion method works almost instantly, when didExitRegion can sometimes fire for 30 seconds or more. Therefore, if you need immediate permission to detect a beacon, you should try to make sure that iBeacon is turned on and not turned off for this ... if possible.

+1
source

Source: https://habr.com/ru/post/1270072/


All Articles