iOS11中“开启蓝牙”提示在控制中心操作时不生效问题求助
嘿,这个问题我之前也碰到过!这是iOS 11之后苹果给控制中心蓝牙开关加的特殊逻辑搞的鬼,咱们一步步捋清楚:
为啥两种关闭方式不一样?
iOS 11起,控制中心的蓝牙快捷开关并不是真的关掉蓝牙硬件——它只是断开当前连接的所有外设,蓝牙模块其实还在低功耗运行,用来支持AirDrop、Handoff还有你用到的iBeacon这些后台依赖蓝牙的功能。而设置里的蓝牙开关才是彻底切断蓝牙硬件的电源。
系统的逻辑是:只有当蓝牙硬件完全断电(设置里关闭)时,才会触发你设置的CBCentralManagerOptionShowPowerAlertKey告警;控制中心关闭时,蓝牙模块没真正停,所以系统觉得没必要弹提示。
怎么让两种情况都能提示用户?
如果你想不管用户用哪种方式关蓝牙,都能引导他们开启,得自己手动处理状态判断和提示:
监听蓝牙状态,自定义提示
在CBCentralManagerDelegate的状态更新方法里,主动判断状态,自己弹提示:- (void)centralManagerDidUpdateState:(CBCentralManager *)central { switch (central.state) { case CBCentralManagerStatePoweredOff: // 手动弹出提示,引导用户去设置开蓝牙 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"蓝牙需要开启" message:@"请前往系统设置开启蓝牙,才能使用iBeacon相关功能" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"去设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { // 跳转到设置页面 NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; if ([[UIApplication sharedApplication] canOpenURL:settingsURL]) { [[UIApplication sharedApplication] openURL:settingsURL options:@{} completionHandler:nil]; } }]]; [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]]; [self presentViewController:alert animated:YES completion:nil]; break; case CBCentralManagerStatePoweredOn: // 蓝牙正常开启,执行你的扫描/监测逻辑 [central scanForPeripheralsWithServices:nil options:nil]; // 同时可以启动CoreLocation的iBeacon监测 break; default: // 处理其他状态(比如未授权、未知错误等) break; } }额外处理控制中心关闭的情况
这里要注意:控制中心关闭蓝牙时,CBCentralManager的状态还是CBCentralManagerStatePoweredOn,但你会发现扫描不到任何外设,iBeacon监测也会停。所以你还得在扫描超时或者CoreLocation的iBeacon回调失败时,再做一层判断——比如弹出提示告诉用户“蓝牙似乎未正常工作,请检查设置”。
最后说两句
苹果这么设计是为了兼顾用户快捷操作和后台蓝牙功能的可用性,所以系统默认的告警只在硬件完全关闭时触发。要覆盖这个行为,只能靠自定义提示来引导用户去设置里操作,毕竟控制中心的开关本质上只是“断连”而非“关闭”。
内容的提问来源于stack exchange,提问作者mhorgan

