You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS 11+ Swift环境下蓝牙开关状态检测异常问题求助

解决iOS 11+ CoreBluetooth始终显示蓝牙关闭的问题

嘿,这个问题我太熟了!iOS 11开始苹果对CoreBluetooth的权限和初始化逻辑做了严格调整,这就是你新系统上代码失效的核心原因,下面给你一步步解决:

1. 必须补充蓝牙权限描述(iOS 11+强制要求)

iOS 11之后,使用CoreBluetooth必须在Info.plist中添加权限说明,否则系统会直接限制蓝牙功能,导致你看到的“始终关闭”状态。

  • 对于iOS 13及以上,需要添加NSBluetoothAlwaysUsageDescription(必填),值填你需要蓝牙的原因,比如"需要蓝牙权限连接智能外设"
  • 如果你还要兼容iOS 11-12,可以同时添加NSBluetoothPeripheralUsageDescription,但这个键在iOS13之后已被废弃,优先用前者

操作方式:直接在Info.plist里右键添加Row,输入对应的键名,然后填写描述文本即可。

2. 修改CBCentralManager初始化逻辑

iOS 11之后,默认初始化CBCentralManager时,系统不会自动弹出蓝牙开启提示。如果用户蓝牙是关闭状态,manager直接进入poweredOff状态,不会引导用户开启。你需要在初始化时添加CBCentralManagerOptionShowPowerAlertKey选项,让系统自动弹出蓝牙开启弹窗。

原代码问题点

你的初始化代码没有传options参数:

manager = CBCentralManager(delegate: self, queue: nil)

修改后的完整代码

import UIKit
import CoreBluetooth

class ViewController: UIViewController,CBCentralManagerDelegate {
    var manager: CBCentralManager!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 添加options参数,让系统自动弹出蓝牙开启提示
        manager = CBCentralManager(delegate: self, queue: nil, options: [CBCentralManagerOptionShowPowerAlertKey: true])
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch (central.state) {
        case .poweredOn:
            print("bluetooth Powered ON")
        case .poweredOff:
            print("bluetooth Powered OFF")
            // 可选:如果系统弹窗没触发,你可以自己加引导弹窗跳转到设置页
            let alert = UIAlertController(title: "蓝牙未开启", message: "请开启蓝牙以使用功能", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "去设置", style: .default, handler: { _ in
                guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return }
                if UIApplication.shared.canOpenURL(settingsUrl) {
                    UIApplication.shared.open(settingsUrl)
                }
            }))
            alert.addAction(UIAlertAction(title: "取消", style: .cancel))
            self.present(alert, animated: true)
        case .unauthorized:
            print("蓝牙权限未授权")
            // 这里可以引导用户去设置开启权限
        case .unknown, .resetting, .unsupported:
            print("蓝牙状态异常:\(central.state.rawValue)")
        @unknown default:
            print("未知蓝牙状态")
        }
    }
}

额外注意事项

  • 测试时一定要用真机!模拟器的蓝牙功能受限,状态显示经常不准确
  • 确保你的设备蓝牙硬件正常,排除硬件故障
  • 如果还是有问题,可以检查是否有其他代码提前终止了CBCentralManager的生命周期

内容的提问来源于stack exchange,提问作者Mohammed Fazil

火山引擎 最新活动