在iOS 10+中,有没有办法可靠地唤醒应用程序

我已经在这3个多月了,把头发拉出来了。 所以请不要回答初学者的答案。

我想知道是否在2017年与iOS 10+,有任何方式可以唤醒终止状态的应用程序…最好通过蓝牙外设…但我会把我能得到的!

我认为终止是当用户在任务pipe理器中刷新应用程序或当外设打开/closures,应用程序已经死亡

我需要在应用程序中维护的重要的与健康有关的BT外围数据(由BT设备logging),所以我需要一致的连接或唤醒应用程序并处理数据的能力。 我知道这是很多的问题,所以我想find最新的理解或解决这个问题。 我已阅读sooo许多文章和SOpost,所以我知道核心蓝牙是不可靠的充其量。 我知道总的概念是片面的,人们自2010年以来一直说不可能。 然而,在iOS中很多地方都在变化,所以我希望事情会发生改变。

要清楚:

BT醒来会很好,但它真的不是可靠的,所以…我会采取任何一种可靠的唤醒(位置,audio,BT等…不是iBeacon,但因为我连接/配对BT设备) 。 如果我必须“破解”在位置或audio上发生的唤醒事件,然后以某种方式快速从外设获取数据,我会接受!

我努力了:

(跳过这个,如果你不关心或不适用)


  • 在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; } } } } 

    恢复中央pipe理者的状态。 这只适用于应用程序被iOS杀死或更改状态。 当用户杀死应用程序时不起作用。

  • 在设备中订阅通知特性(我做了这个自定义的特性,我完全控制了设备的编程)…这个工作真的很好,但并不总是唤醒应用程序。 尽pipe在后台运行良好。 只是没有终止。

  • 在终止时试图完全断开连接,以便我可以使用iBeacon唤醒……太多的环路,并最终无法可靠地工作。
  • 重大的位置更新…非常不可靠
  • audio录制…当开始录制时(无论如何我可以find)没有任何方法会触发,或者在录制过程中间歇性地触发

终于解决了这个问题! 解决scheme是在我的解决scheme中使用2个蓝牙芯片。 一个芯片成为专用的BT连接配对/authentication/保税设备,另一个成为专用的iBeacon广告商。 有了这个解决scheme,我就能够随时唤醒应用程序(通过电源循环iBeacon芯片)并连接BTencryption所需的特性。

使用CLLocationManager类的didEnterRegion方法,在后台,我可以启动蓝牙pipe理器…在后台连接到设备,然后通过先前配对的连接成功检索数据。

更新:作为一个便笺,最好提及的是,虽然iBeacon在后台唤醒应用程序方面相当可靠,但只有在find或打开iBeacon时,才会立即执行didEnterRegion方法。 didExitRegion方法需要(平均)大约30秒的时间才能触发,或者它不在范围之内。