在iOS 10+;中;,有没有可靠的方法唤醒应用程序
我做这件事已经三个多月了。所以,请不要用初学者的答案回答 我想知道2017年iOS 10+是否有任何方法可以将应用程序从终止状态唤醒。。。最好通过蓝牙外围设备。。。但我会拿我能得到的!在iOS 10+;中;,有没有可靠的方法唤醒应用程序,ios,objective-c,bluetooth,cbperipheral,cbcentralmanager,Ios,Objective C,Bluetooth,Cbperipheral,Cbcentralmanager,我做这件事已经三个多月了。所以,请不要用初学者的答案回答 我想知道2017年iOS 10+是否有任何方法可以将应用程序从终止状态唤醒。。。最好通过蓝牙外围设备。。。但我会拿我能得到的! 我认为终止是在用户在任务管理器中点击应用程序或当外围设备打开/关闭时,应用程序已经死亡 我需要在应用程序中维护与健康相关的重要BT外围数据(由BT设备记录),因此我需要一致的连接或唤醒应用程序并处理数据的能力。我知道这是问了很多,所以我试图找到最新的理解或解决这个问题的办法。我已经读了很多关于这方面的文章和S.O
我认为终止是在用户在任务管理器中点击应用程序或当外围设备打开/关闭时,应用程序已经死亡
我需要在应用程序中维护与健康相关的重要BT外围数据(由BT设备记录),因此我需要一致的连接或唤醒应用程序并处理数据的能力。我知道这是问了很多,所以我试图找到最新的理解或解决这个问题的办法。我已经读了很多关于这方面的文章和S.O.的帖子,所以我知道核心蓝牙充其量是不可靠的。我知道一般的概念是脆弱的,自2010年以来人们一直在说这是不可能的。然而,在iOS中很多东西都在变化,所以我希望有些东西会改变 要清楚: BT唤醒将是伟大的,但它真的不可靠,所以。。。我将采取任何形式的可靠唤醒(位置、音频、BT等…但不是iBeacon,因为我已连接/配对到BT设备)。如果我必须“黑客”唤醒发生在位置或音频上,然后以某种方式从外设快速获取数据,我会接受它 我试过: (如果您不在乎或不适用,请跳过此项)- 在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; } } } }
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关闭或状态更改时有效。当用户终止应用程序时不起作用-(BOOL)应用程序:(UIApplication*)应用程序将使用选项完成启动:(NSDictionary*)启动选项{ NSLog(@“找到的启动选项:%@”,启动选项); NSArray*centralManagerIdentifiers=启动选项[UIApplicationLaunchOptions蓝色中心键]; NSLog(@“在启动选项中找到的中央管理器:%@”,中央管理器标识符); [self-triggerLocalNotification:[NSString stringWithFormat:@“在启动选项中找到的中央管理器:%@”,中央管理器标识符]]; 如果([centralManagerIdentifiers计数]>0){ for(centralManagerIdentifiers中的NSString*标识符){ if([标识符IsequalString:@“MyDevice”]){ [self-triggerLocalNotification:[NSString stringWithFormat:@“找到的标识符:%@”,标识符]]; self.bluetoothManager=[BluetoothMgr sharedInstance]; } } } 返回YES; } -(无效)中央经理:(CBCentralManager*)中央 willRestoreState:(NSDictionary*)州{ NSLog(@“*************恢复状态BT*******************”); [自触发CustomLocalNotification:@“****************还原状态BT*******************”; NSLog(@“中央管理器对象:%@”,中央); NSLog(@“状态字典:%@”,状态); [自触发CustomLocalNotification:[NSString stringWithFormat:@“状态字典:%@”,状态]]; NSArray*restoredPeripherals=[状态对象forkey:@“CBCentralManagerRestoredStatePeripheralsKey]; self.centralManager=central; self.centralManager.delegate=self; 如果([restoredPeripherals count]>0){ 用于(恢复的外围设备中的CBPeripheral*外围设备){ if([peripheral.name rangeOfString:@“mybox-”].location!=NSNotFound){ NSLog(@“还原mybox:%@”,外围设备); [self-triggerCustomLocalNotification:[NSString stringWithFormat:@”发现外围设备处于将恢复状态!它是:%@,外围设备]]; self.myperipal=外围设备; self.myperipal.delegate=self; [自连接设备]; 返回; } } } }
- 订阅设备中的通知特性(我制作了这个自定义特性,我完全可以控制设备的编程)。。。这确实很好,但并不总是唤醒应用程序。不过在后台效果很好。只是没有终止
- 尝试在终止后完全断开连接,以便我可以使用iBeacon唤醒。。。太多的箍环,最终它根本不能可靠地工作
- 重要的位置更新。。。极不可靠
- 录音。。。没有方法在开始录制时触发(我无论如何都可以找到),也没有方法在录制时间歇性触发
- 终于解决了这个问题!解决方案是在我的解决方案中使用2个蓝牙芯片。一个芯片是专用的BT连接配对/认证/绑定设备,另一个是专用的iBeacon广告商。有了这个解决方案,我可以随时唤醒应用程序(通过随意给iBeacon芯片通电)和连接BT加密所需的特性
使用
CLLocationManager
类的didEnterRegion
方法,我可以在后台启动bluetooth manager。。。在后台连接到设备,然后通过先前配对的连接成功检索数据
更新:作为旁注,值得一提的是,虽然iBeacon在后台唤醒应用程序时相当可靠,但只有当找到或打开iBeacon时,
didEnterRegion
方法才会立即发生。didExitRegion
方法在我关闭iBeacon或它不再在射程内后(平均)大约需要30秒才能开火。@GoraDefex我需要你的帮助。请看我的问题:@GoreDefex请看这个问题。我还需要同样的答案:stackoverflow.com/questions/47813624