在 iOS 10+ 中,是否有任何方法可以可靠地唤醒应用程序
In iOS 10+, is there ANY way to RELIABLY wake up an app
我已经用了 3 个多月了,一直在努力。所以请不要用初学者的答案来回应。
我想知道,在 2017 年 iOS 10+ 时,是否有任何方法可以将应用程序从终止状态唤醒......最好是通过蓝牙外围设备......但我会采取什么我可以得到!
我认为当用户在任务管理器中滑动应用程序或当外围设备被打开时on/off并且应用程序已经死了
我需要在应用程序中维护与健康相关的重要 BT 外围设备数据(由 BT 设备记录),因此我需要一致的连接或唤醒应用程序备份和处理数据的能力。我知道这被问了很多,所以我试图找到这个问题的最新理解或解决方案。我已经阅读了很多文章和 S.O。关于此的帖子所以我知道 Core Bluetooth 充其量是不可靠的。我知道一般概念是不稳定的,自 2010 年以来人们一直在说这是不可能的。但是,iOS 中的很多内容都在不断变化,所以我希望有些事情会有所改变。
要明确:
BT 唤醒会很棒,但它确实不可靠,所以...我会采用任何可靠的唤醒方式(位置、音频、BT 等...不是 iBeacon,因为我是 connected/paired 到 BT 设备)。如果我必须 "hack" 在位置或音频上唤醒,然后以某种方式快速从外围设备获取数据,我会接受它!
我试过了:
(如果您不关心或不适用,请跳过)
- 已在 info.plist
开启后台中央模式
使用全状态还原,也就是说这段代码...
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self
queue:nil
options:@{CBCentralManagerOptionShowPowerAlertKey: @(YES),
CBCentralManagerOptionRestoreIdentifierKey:@"MyDevice"}];
要注册标识符密钥和此代码...
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(@"launch options found: %@", launchOptions);
NSArray *centralManagerIdentifiers = launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey];
NSLog(@"central managers found in launch options: %@", centralManagerIdentifiers);
[self triggerLocalNotification:[NSString stringWithFormat:@"central managers found in launch options: %@", centralManagerIdentifiers]];
if([centralManagerIdentifiers count] > 0) {
for(NSString *identifier in centralManagerIdentifiers) {
if([identifier isEqualToString:@"MyDevice"]) {
[self triggerLocalNotification:[NSString stringWithFormat:@"Identifier found: %@", identifier]];
self.bluetoothManager = [BluetoothMgr sharedInstance];
}
}
}
return YES;
}
- (void)centralManager:(CBCentralManager *)central
willRestoreState:(NSDictionary<NSString *,id> *)state {
NSLog(@"************** RESTORED STATE BT **************");
[self triggerCustomLocalNotification:@"************** RESTORED STATE BT **************"];
NSLog(@"central manager object: %@", central);
NSLog(@"state dictionary: %@", state);
[self triggerCustomLocalNotification:[NSString stringWithFormat:@"state dictionary: %@", state]];
NSArray *restoredPeripherals = [state objectForKey:@"CBCentralManagerRestoredStatePeripheralsKey"];
self.centralManager = central;
self.centralManager.delegate = self;
if([restoredPeripherals count] > 0) {
for(CBPeripheral *peripheral in restoredPeripherals) {
if([peripheral.name rangeOfString:@"mybox-"].location != NSNotFound) {
NSLog(@"Restoring mybox Box: %@", peripheral);
[self triggerCustomLocalNotification:[NSString stringWithFormat:@"Peripheral was found in WILL RESTORE STATE! it was: %@", peripheral]];
self.myPeripheral = peripheral;
self.myPeripheral.delegate = self;
[self connectToDevice];
return;
}
}
}
}
恢复中央管理器状态。这仅在应用程序被 iOS 杀死或状态更改时有效。当用户终止应用程序时不起作用。
订阅设备中的通知特性(我制作了这个自定义特性并且我完全控制了设备的编程)......这非常有效但并不总是唤醒应用程序向上。虽然在后台运行良好。只是没有终止。
- 尝试在终止时完全断开连接,以便我可以使用 iBeacon 重新唤醒...太多的麻烦,最终它根本无法可靠地工作。
- 重要位置更新...极不可靠
- 录音...开始录音时没有方法触发(无论如何我都能找到)或者在录音时间歇性触发的方法
终于解决了这个问题!解决方案是在我的解决方案中使用 2 个蓝牙芯片。一个芯片是专用的 BT 连接 Paired/Auth/Bonded 设备,另一个是专用的 iBeacon 广告商。有了这个解决方案,我能够同时唤醒应用程序(通过随意对 iBeacon 芯片进行电源循环)和连接以获得 BT 加密所需的特性。
使用CLLocationManager
class的didEnterRegion
方法,在后台,我可以启动蓝牙管理器...在后台连接到设备,然后检索通过先前配对的连接成功传输数据。
更新: 作为旁注,值得一提的是,虽然 iBeacon 在后台唤醒应用程序方面相当可靠,但只有 didEnterRegion
方法当 iBeacon 被发现或打开时立即发生。 didExitRegion
方法在我关闭 iBeacon 或它不再在范围内后(平均)需要大约 30 秒才能触发。
我已经用了 3 个多月了,一直在努力。所以请不要用初学者的答案来回应。
我想知道,在 2017 年 iOS 10+ 时,是否有任何方法可以将应用程序从终止状态唤醒......最好是通过蓝牙外围设备......但我会采取什么我可以得到!
我认为当用户在任务管理器中滑动应用程序或当外围设备被打开时on/off并且应用程序已经死了
我需要在应用程序中维护与健康相关的重要 BT 外围设备数据(由 BT 设备记录),因此我需要一致的连接或唤醒应用程序备份和处理数据的能力。我知道这被问了很多,所以我试图找到这个问题的最新理解或解决方案。我已经阅读了很多文章和 S.O。关于此的帖子所以我知道 Core Bluetooth 充其量是不可靠的。我知道一般概念是不稳定的,自 2010 年以来人们一直在说这是不可能的。但是,iOS 中的很多内容都在不断变化,所以我希望有些事情会有所改变。
要明确:
BT 唤醒会很棒,但它确实不可靠,所以...我会采用任何可靠的唤醒方式(位置、音频、BT 等...不是 iBeacon,因为我是 connected/paired 到 BT 设备)。如果我必须 "hack" 在位置或音频上唤醒,然后以某种方式快速从外围设备获取数据,我会接受它!
我试过了:
(如果您不关心或不适用,请跳过)
- 已在 info.plist 开启后台中央模式
使用全状态还原,也就是说这段代码...
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionShowPowerAlertKey: @(YES), CBCentralManagerOptionRestoreIdentifierKey:@"MyDevice"}];
要注册标识符密钥和此代码...
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSLog(@"launch options found: %@", launchOptions); NSArray *centralManagerIdentifiers = launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey]; NSLog(@"central managers found in launch options: %@", centralManagerIdentifiers); [self triggerLocalNotification:[NSString stringWithFormat:@"central managers found in launch options: %@", centralManagerIdentifiers]]; if([centralManagerIdentifiers count] > 0) { for(NSString *identifier in centralManagerIdentifiers) { if([identifier isEqualToString:@"MyDevice"]) { [self triggerLocalNotification:[NSString stringWithFormat:@"Identifier found: %@", identifier]]; self.bluetoothManager = [BluetoothMgr sharedInstance]; } } } return YES; } - (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *,id> *)state { NSLog(@"************** RESTORED STATE BT **************"); [self triggerCustomLocalNotification:@"************** RESTORED STATE BT **************"]; NSLog(@"central manager object: %@", central); NSLog(@"state dictionary: %@", state); [self triggerCustomLocalNotification:[NSString stringWithFormat:@"state dictionary: %@", state]]; NSArray *restoredPeripherals = [state objectForKey:@"CBCentralManagerRestoredStatePeripheralsKey"]; self.centralManager = central; self.centralManager.delegate = self; if([restoredPeripherals count] > 0) { for(CBPeripheral *peripheral in restoredPeripherals) { if([peripheral.name rangeOfString:@"mybox-"].location != NSNotFound) { NSLog(@"Restoring mybox Box: %@", peripheral); [self triggerCustomLocalNotification:[NSString stringWithFormat:@"Peripheral was found in WILL RESTORE STATE! it was: %@", peripheral]]; self.myPeripheral = peripheral; self.myPeripheral.delegate = self; [self connectToDevice]; return; } } } }
恢复中央管理器状态。这仅在应用程序被 iOS 杀死或状态更改时有效。当用户终止应用程序时不起作用。
订阅设备中的通知特性(我制作了这个自定义特性并且我完全控制了设备的编程)......这非常有效但并不总是唤醒应用程序向上。虽然在后台运行良好。只是没有终止。
- 尝试在终止时完全断开连接,以便我可以使用 iBeacon 重新唤醒...太多的麻烦,最终它根本无法可靠地工作。
- 重要位置更新...极不可靠
- 录音...开始录音时没有方法触发(无论如何我都能找到)或者在录音时间歇性触发的方法
终于解决了这个问题!解决方案是在我的解决方案中使用 2 个蓝牙芯片。一个芯片是专用的 BT 连接 Paired/Auth/Bonded 设备,另一个是专用的 iBeacon 广告商。有了这个解决方案,我能够同时唤醒应用程序(通过随意对 iBeacon 芯片进行电源循环)和连接以获得 BT 加密所需的特性。
使用CLLocationManager
class的didEnterRegion
方法,在后台,我可以启动蓝牙管理器...在后台连接到设备,然后检索通过先前配对的连接成功传输数据。
更新: 作为旁注,值得一提的是,虽然 iBeacon 在后台唤醒应用程序方面相当可靠,但只有 didEnterRegion
方法当 iBeacon 被发现或打开时立即发生。 didExitRegion
方法在我关闭 iBeacon 或它不再在范围内后(平均)需要大约 30 秒才能触发。