CoreBluetooth状态preservation问题:willRestoreState不是在iOS的7.1叫 [英] CoreBluetooth state preservation issue: willRestoreState not called in iOS 7.1

查看:2690
本文介绍了CoreBluetooth状态preservation问题:willRestoreState不是在iOS的7.1叫的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

CoreBluetooth状态preservation问题:在iOS的7.1 willRestoreState不叫

CoreBluetooth state preservation issue: willRestoreState not called in iOS 7.1

嘿所有。我一直对蓝牙LE项目在过去几个星期,并创下了路障。我一直无法得到恢复状态,在iOS中7 / 7.1正常工作。我跟着(我认为)所有的苹果勾画出的步骤,并得到了其他堆栈溢出的职位一些线索。

Hey all. I’ve been working on a Bluetooth LE project for the past few weeks, and hit a roadblock. I have been unable to get state restoration working properly in iOS 7 / 7.1. I’ve followed (I think) all of the steps Apple lays out, and got some clues on other stack overflow posts.


  1. 我加入了适当的蓝牙权限的plist

  2. 当我创建我中心经理,我给它一个恢复标识符键。

  3. 我总是实例使用相同的密钥
  4. 的CM
  5. 我加入了willRestoreState功能将CM代表

我的测试案例:


  1. 连接到外围

  2. 确认连接

  3. 模拟内存驱逐(杀号(getpid(),SIGKILL);)

  4. 发送数据

结果的iOS 7:

该应用程序将在AppDelegate中didFinishLaunchingWithOptions响应函数,但是NSArray中的launchOptions [UIApplicationLaunchOptionsBluetoothCentralsKey]里面的内容总是一个空数组。

The app would respond in the AppDelegate didFinishLaunchingWithOptions function, but the contents of the NSArray inside of launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey] was always an empty array.

结果在iOS 7.1:

Results on iOS 7.1:

进展!我可以看到的时间UIApplicationLaunchOptionsBluetoothCentralsKey阵列100%我CentralManager关键,但willRestoreState不会被调用。

Progress! I can see my CentralManager key in the UIApplicationLaunchOptionsBluetoothCentralsKey array 100% of the time, but willRestoreState is never called.

code:

//All of this is in AppDelegate for testing

@import CoreBluetooth;
@interface AppDelegate () <CBCentralManagerDelegate, CBPeripheralDelegate>
@property (readwrite, nonatomic, strong) CBCentralManager *centralManager;
@end

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

    self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionRestoreIdentifierKey:@"myCentralManager"}];

    //Used to debug CM restore only
    NSArray *centralManagerIdentifiers = launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey];
    NSString *str = [NSString stringWithFormat: @"%@ %lu", @"Manager Restores: ", (unsigned long)centralManagerIdentifiers.count];
    [self sendNotification:str];
    for(int i = 0;i<centralManagerIdentifiers.count;i++)
    {
        [self sendNotification:(NSString *)[centralManagerIdentifiers objectAtIndex:i]];
    }

    return YES;
}

- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)state {
    activePeripheral = [state[CBCentralManagerRestoredStatePeripheralsKey] firstItem];
    activePeripheral.delegate = self;

    NSString *str = [NSString stringWithFormat: @"%@ %lu", @"Device: ", activePeripheral.UUID];
    [self sendNotification:str];
}

//sendNotification is a func that creates a local notification for debugging when device connected to comp

当我运行测试,didFinishLaunchWithOptions被称为100%的时候,我BLE装置时,应用程序是不是在内存中的电话通信,但willRestoreState不会被调用。

When I run the tests, didFinishLaunchWithOptions is called 100% when my BLE device communicates to the phone when the app is not in memory, but willRestoreState is never called.

任何及所有帮助将是巨大的!谢谢!

Any and all help would be great! thanks!

推荐答案

好了,所以我不得不删除我的两个答案已经到了这个问题。但是我想我终于想通了。

Okay, so I've had to delete two of my answers already to this question. But I think I've finally figured it out.

此注释的关键是你的问题。从本质上讲,这 centralManager:willRestoreState:如果它的动力由操作系统关闭,而一个优秀的操作过程中,与外围设备(仅适用于被称为这不包括扫描外围线在进一步的调查,如果你扫描了服务的UUID和应用程序被以同样的方式杀害,或者你已经完成连接,这将在事实上打电话给你的代表)。

This comment is the key to your problem. Essentially, this centralManager:willRestoreState: only gets called if it's force closed by the OS while an outstanding operation is in progress with a peripheral (this does not include scanning for peripherals On further investigation, if you're scanning for a service UUID and the app is killed in the same way, or you've already finished connecting, it will in fact call your delegate).

要复制:
我有一个外围使用CoreBluetooth建立在我的MacBook。我做广告的外围设备,并有中央在我的iPhone发现它。然后,离开OSX外围应用程序的运行,杀死你的Mac上的BT连接,然后开始从中央一个连接你的iOS设备上。这显然​​将连续运行的外围是无法访问的(显然,连接尝试能够天长地久蓝牙LE对连接没有超时)。然后,我添加了一个按钮,我的GUI,并在我的视图控制器迷上它给一个函数:

To replicate: I have a peripheral using CoreBluetooth set up on my MacBook. I advertise on the peripheral, and have the central on my iPhone discover it. Then, leaving the OSX peripheral app running, kill your BT connection on your Mac and then initiate a connect from the central on your iOS device. This obviously will continuously run as the peripheral is non-reachable (apparently, the connection attempt can last forever as Bluetooth LE has no timeout on connections). I then added a button to my gui and hooked it up to a function in my view controller:

- (IBAction)crash:(id)sender
{
    kill(getpid(), SIGKILL);
}

这将杀死应用程序,如果它是由操作系统杀害。一旦你试图连接水龙头的按钮崩溃的应用程序(有时需要两个水龙头)。

This will kill the app as if it was killed by the OS. Once you are attempting to connect tap the button to crash the app (sometimes it takes two taps).

激活蓝牙的Mac上便会导致的iOS重振您的应用程序并调用正确的处理程序(包括 centralManager:willRestoreState:)。

Activating Bluetooth on your Mac will then result in iOS relaunching your app and calling the correct handlers (including centralManager:willRestoreState:).

如果您要调试的处理程序(通过设置断点),在X code本的Mac上开启BT之前,设置一个断点,然后选择调试>附加到进程...>通过流程标识或名称...

If you want to debug the handlers (by setting a breakpoint), in Xcode, before turning BT on on your Mac, set a breakpoint and then select 'Debug > Attach to Process... > By Process Identifier or Name...'.

在出现,键入您的应用程序的名称的对话框(应该是相同的,以你的目标),然后单击连接。那么X code会说在状态窗口等待发射。等待几秒钟,然后再打开BT在OSX。确保你的周围尚广告后,iOS将它捡起来并重新启动您的应用程序来处理连接。

In the dialog that appears, type the name of your app (should be identical to your target) and click "Attach". Xcode will then say waiting for launch in the status window. Wait a couple seconds and then turn on BT on OSX. Make sure your peripheral is still advertising and then iOS will pick it up and relaunch your app to handle the connection.

有可能其他的方法来测试这个(使用通知上的特性,也许?),但这个流量是100%可重复这样可能会帮助你最容易考验你code。

There are likely other ways to test this (using notify on a characteristic maybe?) but this flow is 100% reproducible so will likely help you test you code most easily.

这篇关于CoreBluetooth状态preservation问题:willRestoreState不是在iOS的7.1叫的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆