在iOS 10+中,有没有什么方法可以唤醒应用程序

时间:2017-08-17 15:09:48

标签: ios objective-c bluetooth cbperipheral cbcentralmanager

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

我想知道,在2017年使用iOS 10+时,是否有任何方法可以将应用程序从终止状态唤醒...最好是通过蓝牙外设...但我会采取我能得到的东西!

我认为当用户在任务管理器中刷过应用程序或打开/关闭外围设备并且应用程序已经死亡时

我需要在应用程序中维护重要的健康相关BT外围数据(由BT设备记录),因此我需要一致的连接或唤醒应用程序备份和处理数据的能力。我知道这被问了很多,所以我试图找到对这个问题的最新理解或解决方案。我读过很多文章和S.O.关于此的帖子,所以我知道Core Bluetooth充其量是不可靠的。我知道一般的概念是不稳定的,人们自2010年以来就说不可能。但是,iOS中的批量不断变化,所以我希望有些东西会发生变化。

要明确:

BT唤醒会很棒,但它确实不可靠,所以......我会采取任何可靠的唤醒方式(位置,音频,BT等等......不是iBeacon,因为我是连接/配对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唤醒...太多的箍,最后它根本无法正常工作。
  • 重要的位置更新......非常不可靠
  • 音频录制......开始录制时无法触发(无论如何我都能找到)或录制时间歇性发射的方法

1 个答案:

答案 0 :(得分:2)

终于解决了这个问题!解决方案是在我的解决方案中使用2个蓝牙芯片。一个芯片是专用的BT连接配对/验证/绑定设备,另一个芯片是专用的iBeacon广告商。通过这个解决方案,我可以同时唤醒应用程序(通过随意重启iBeacon芯片)和连接BT加密所需的特性。

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

更新:作为附注,值得一提的是,虽然iBeacon在后台唤醒应用程序时非常可靠,但只发生了didEnterRegion方法立即找到或打开iBeacon。关闭iBeacon后,didExitRegion方法让我(平均)大约需要30秒才能启动,或者它不在范围内。