You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何将蓝牙状态存储到变量并用于POST API?

解决CBCentralManager状态异步更新导致变量未赋值的问题

问题原因

CBCentralManager的状态更新是异步回调的:初始化manager后,系统需要时间检测蓝牙状态,centralManagerDidUpdateState方法的调用时机晚于viewWillAppear,所以此时isBTTurnedOn还是初始的nil值。

解决方案

通过两种方式确保状态变量被正确赋值并可用于API请求:

  • 提取状态更新逻辑为复用方法,既支持代理回调触发,也支持主动检查状态
  • 在状态更新后直接触发POST请求,避免依赖页面生命周期方法的时机

修改后的代码示例

class ViewController: UIViewController, CBCentralManagerDelegate {
    
    var isBTTurnedOn: Bool?
    var manager: CBCentralManager!

    override func viewDidLoad() {
        super.viewDidLoad()
        // 初始化时指定主队列,确保回调在主线程执行(适配UI操作)
        manager = CBCentralManager(delegate: self, queue: DispatchQueue.main)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 主动检查当前蓝牙状态,避免等待异步回调
        updateBTState(with: manager.state)
        print("Bt status is \(isBTTurnedOn)")
    }
    
    // 复用的状态更新方法
    private func updateBTState(with state: CBManagerState) {
        switch state {
        case .poweredOn:
            print("Bluetooth is ON.")
            isBTTurnedOn = true
            // 状态确认后立即调用POST API
            sendBTStatusToAPI()
        case .poweredOff:
            print("Bluetooth is Off.")
            isBTTurnedOn = false
            sendBTStatusToAPI()
        @unknown default:
            isBTTurnedOn = nil
        }
    }
    
    // 代理方法调用复用逻辑
    public func centralManagerDidUpdateState(_ central: CBCentralManager) {
        updateBTState(with: central.state)
    }
    
    // POST API请求示例
    private func sendBTStatusToAPI() {
        guard let btStatus = isBTTurnedOn else { return }
        
        // 构建请求参数
        let parameters = ["bluetooth_enabled": btStatus]
        // 这里实现你的URLSession或第三方网络库请求逻辑
        guard let url = URL(string: "你的API地址") else { return }
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = try? JSONSerialization.data(withJSONObject: parameters)
        
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error {
                print("API请求失败:\(error)")
                return
            }
            print("蓝牙状态已成功提交")
        }
        task.resume()
    }
}

关键说明

  • 初始化CBCentralManager时指定主队列,确保状态回调在主线程执行,避免线程冲突
  • 复用updateBTState方法,既可以在viewWillAppear主动检查状态,也能响应代理的异步回调,保证isBTTurnedOn始终有正确值
  • 在状态更新后直接调用sendBTStatusToAPI,确保只有当状态明确时才发起请求,避免传递nil值到API

内容的提问来源于stack exchange,提问作者Tanishq Arora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 03:55:14