问题描述
我有一个用例,我的 Objective-c 应用程序需要在它终止后立即使用 iBeacon,以便将应用程序从终止状态唤醒,连接到 BLE 并向设备发送命令.我有一个更大的运行时间更长的在这里找到的帖子 如果需要,您可以查看我的代码.
I have a use case where my objective-c application needs to immediately use iBeacon after it's been terminated in order to wake the application up from a terminated state, connect to BLE and send a command to the device. I have a larger longer running post found here that you can check out for my code if need be.
问题
到目前为止,问题发生在我运行应用程序、搜索以前配对的设备和/或扫描外围设备、找到我的 BLE 设备并连接时.连接后,用户配对 BLE 连接,以便他们可以通过 BLE 连接发送加密的特征数据.如果没有配对(也就是设备命名约定中的 auth/bond),用户根本无法将数据发送到设备.它永远不会到达那里.配对后就可以发送命令...
The problem so far, happens when I run the application, search for previously paired devices and/or scan for peripherals, find my BLE device and connect. Once connected the user pairs the BLE connection so that they can send encrypted characteristic data over BLE connection. Without pairing (aka auth/bond in the device's naming conventions) the user cannot send the data to the device at all. It never makes it there. As soon as you pair you can send the command...
当我终止应用程序时,在 applicationWillTerminate
方法中,我运行了这段代码...
When I terminate the app, in the applicationWillTerminate
method, I run through 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!");
}
}
我想要完成的事情
magiccommand1
和 magiccommand2
命令只是设备通过串行端口侦听的愚蠢的测试字符串(现在是 128 位令牌).一旦他们收到命令,他们就会尝试擦除设备上的身份验证/绑定,并与设备中的 BLE 断开连接.
The magiccommand1
and magiccommand2
commands are just silly test strings (for now, 128 bit tokens later) that the device is listening for over the serial port. Once they receive the commands they react by attempting to wipe the auth/bond on the device and also disconnecting from BLE in the device.
因此,我似乎可以让应用程序从终止状态唤醒的唯一方法是使用 iBeacon.所以我不得不在这里做一堆看似肮脏的事情,只是为了把这个圆钉插入一个方孔.在应用程序的生命周期中,它连接并配对,当我终止时,我希望它作为连接设备从 BLE 中完全删除.我希望 iBeacon 将唤醒应用程序,连接回 BLE,关闭 iBeacon 监控,然后从终止状态向 BLE 设备发送命令.从 iBeacon 到 BLE 的打开/关闭或连接/断开连接很可能会导致用户必须重新配对,而我不希望这样.
So the only way I can seem to get the app to wake up from a terminated state is with iBeacon. So I am having to do a bunch of seemingly dirty stuff here just to get this round peg in a square hole. In the app's lifecycle it connects and pairs and when I terminate I want it to completely be removed as a connected device from BLE. My hope is that iBeacon will wake up the app, connect back to BLE, shut off iBeacon monitoring and then send a command to the BLE device from a terminated state. This turning on/off or connecting/disconnecting from iBeacon to BLE and back would most likely cause the user to have to re-pair and I don't want this.
更多问题
当我调用 [self.centralManager cancelPeripheralConnection:self.thePeripheral];
iOS 系统级 BT 管理器似乎几乎立即自动重新连接(因为配对)所以没有时间连接被切断,iBeacon 被再次捡起.如果我在将断开连接命令发送到我的盒子之前尝试从我的 centralManager
实例断开连接(如上面注释掉的代码所示),它们显然也不会发送.如果我只使用 CBCentralManager
断开连接方法,iBeacon 还不足以开始被检测到,因为 iOS 系统仍然与设备配对.最后,如果我进入我的 iOS 系统 BT 管理器并选择忘记这个设备",iBeacon 将再次被拿起并且我的 didEnterRegion
方法被触发!
When I call [self.centralManager cancelPeripheralConnection:self.thePeripheral];
the iOS system level BT manager seems to auto reconnect almost instantly (because of the pairing) so there is no time for the connection to be severed and iBeacon to be picked up again. If I attempt to disconnect from my centralManager
instance before sending the disconnect command to my box (as seen above in code commented out) they obviously wont send either. If I just use only that CBCentralManager
disconnect method it isn't enough for iBeacon to begin being detected as the iOS system is still paired with the device. Lastly, if I then go into my iOS system BT manager and choose "Forget this device", the iBeacon gets picked up again and my didEnterRegion
method fires!
这是 iBeacon 和 BLE 之间的很多来回,我只是希望我什至不需要 iBeacon 来唤醒应用程序.我打开了所有 info.plist 后台 BLE 和 iBeacon 服务.如果我根本没有连接到 BLE 并且从不配对一次并连接我的设备,则本地应用程序通知会毫无问题地滑入,让我知道 iBeacon didEnterRegion
和 didExitRegion
方法可以毫无问题地被触发.
This is a lot of back and forth between iBeacon and BLE and I just wish I didn't even need iBeacon to wake up the app. I have all info.plist background BLE and iBeacon services turned on. If I don't connect to BLE at all and never pair once and connect my device, the local app notifications slide in without problem letting me know that the iBeacon didEnterRegion
and didExitRegion
methods are being fired without trouble.
我在这里做错了什么?
推荐答案
我想出了这个答案!我有点走在正确的道路上...尝试断开 BT 配对以尝试触发 iBeacon 委托方法并不是一个好主意.它导致了许多奇怪的脏代码,不应该出现的紧密耦合的东西,更糟糕的是……可怕的意大利面条式代码.
I figured out this answer! I was sort of on the right path... It's not a great idea to try and disconnect from BT pairing in order to try to get iBeacon delegate methods to fire. It causes a lot of weird dirty code, tightly coupled things that shouldn't be and worse... the dreaded spaghetti code.
相反,我的解决方案是构建一个带有 2 个蓝牙芯片的电路板.一个作为专用 iBeacon 芯片,另一个作为永久连接/配对/认证和绑定芯片.这样就不需要监视任何定时连接和断开连接事件(或者更糟的是......解决了竞争条件).在 iOS 中等待设备断开连接并不是真正的断开连接,而是当 iOS 系统认为它断开连接时(在手机方面).外围系统内部发生的事情描绘了一幅非常不同的画面......
Instead my solution was to build a board with 2 Bluetooth chips in it. One as a dedicated iBeacon chip and the other as a permanent connected/paired/auth and bonded chip. This way there does not need to be any timed connection and disconnection events to be monitored (or worse... resolved race conditions). Waiting for a device to disconnect in iOS is not a true disconnect, it is instead when the iOS system thinks it's disconnected (in the phone's side of things). The things going on inside of the peripheral system paint a very different picture...
这种 2 芯片方法使开发方面的工作变得更加轻松,因为现在无论何时您需要唤醒应用程序来处理某些事情,您都可以重启 iBeacon 设备并接收适当的事件.
This 2 chip approach made life so much easier on the development side because now anytime you need the application to wake up to handle something, you can power cycle the iBeacon device and receive the appropriate event.
附注:当使用 iBeacon 时,didEnterRegion
方法几乎立即触发,而 didExitRegion
有时可能需要 30 秒或更长时间才能触发.因此,如果您需要即时的信标检测解决方案,您应该尝试确保 iBeacon 正在开启而不是关闭……如果可能的话.
Side note: When using iBeacon the didEnterRegion
method fires almost instantly where as the didExitRegion
can take 30 or more seconds sometimes to fire. Therefore if you need immediate beacon detection resolution you should try to make sure the iBeacon is being powered on and not off for this... if even possible.
这篇关于OBJ-C 操作方法:在同一设备中使用 BLE 连接和 iBeacon 的应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!