iOS蓝牙开发:点击APP按钮无数据发至外设,外设与特征值为nil排查
Why Your Bluetooth Write Isn't Working (Peripheral/Characteristic Are Nil)
It sounds like the core issue here is that your TemperatureViewController isn’t properly accessing the Bluetooth objects managed in AppDelegate, or those objects aren’t being passed/updated correctly when the peripheral connects and characteristics are discovered. Let’s break down the exact causes and how to fix them:
Common Root Causes
- Your ViewController has uninitialized, separate Bluetooth objects: The
centralManager,heartRatePeripheral, andcharacteristicinTemperatureViewControllerare not linked to the working instances inAppDelegate—they’re never assigned values, so they stay nil. - No communication between AppDelegate and ViewController: When
AppDelegatediscovers a peripheral or characteristic, it doesn’t notify your ViewController to update its references. - You’re calling
writeValuetoo early: If the button is pressed before the peripheral is connected and the target characteristic is fully discovered, those variables will still be nil.
Step-by-Step Fixes
1. Expose AppDelegate’s Bluetooth Instances
First, update your AppDelegate to make its Bluetooth properties accessible to other parts of the app, and ensure it properly tracks connected peripherals and characteristics:
import UIKit import CoreBluetooth @main class AppDelegate: UIResponder, UIApplicationDelegate, CBCentralManagerDelegate, CBPeripheralDelegate { var window: UIWindow? var centralManager: CBCentralManager! var connectedPeripheral: CBPeripheral? var targetWriteCharacteristic: CBCharacteristic? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { centralManager = CBCentralManager(delegate: self, queue: nil) return true } // MARK: - CBCentralManagerDelegate func centralManagerDidUpdateState(_ central: CBCentralManager) { if central.state == .poweredOn { // Replace with your peripheral's service UUID centralManager.scanForPeripherals(withServices: [CBUUID(string: "YOUR_SERVICE_UUID")]) } } func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { centralManager.connect(peripheral, options: nil) connectedPeripheral = peripheral peripheral.delegate = self } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { peripheral.discoverServices([CBUUID(string: "YOUR_SERVICE_UUID")]) } // MARK: - CBPeripheralDelegate func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { guard let services = peripheral.services else { return } for service in services { // Replace with your characteristic's UUID peripheral.discoverCharacteristics([CBUUID(string: "YOUR_WRITE_CHAR_UUID")], for: service) } } func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { guard let characteristics = service.characteristics else { return } for char in characteristics { if char.uuid == CBUUID(string: "YOUR_WRITE_CHAR_UUID") { targetWriteCharacteristic = char // Notify ViewController the characteristic is ready to use NotificationCenter.default.post(name: NSNotification.Name("CharacteristicReady"), object: nil) } } } }
2. Update Your ViewController to Use AppDelegate’s Objects
Modify your TemperatureViewController to access the shared Bluetooth instances from AppDelegate, and add safeguards to avoid nil references:
import UIKit import CoreBluetooth class TemperatureViewController: UIViewController { // Remove local Bluetooth properties—we'll use AppDelegate's instead // var centralManager: CBCentralManager! // var heartRatePeripheral: CBPeripheral! // var characteristic: CBCharacteristic? @IBOutlet weak var sendValueButton: UIButton! override func viewDidLoad() { super.viewDidLoad() // Disable button until characteristic is ready sendValueButton.isEnabled = false // Listen for notification from AppDelegate when characteristic is discovered NotificationCenter.default.addObserver(self, selector: #selector(enableWriteButton), name: NSNotification.Name("CharacteristicReady"), object: nil) } @objc func enableWriteButton() { sendValueButton.isEnabled = true } // Button action to send value @IBAction func sendValueTapped(_ sender: UIButton) { writeValue(value: 25) // Example temperature value } func writeValue(value: Int8) { // Get reference to AppDelegate guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { print("Failed to access AppDelegate") return } // Validate all required objects exist and support writing guard let peripheral = appDelegate.connectedPeripheral, let characteristic = appDelegate.targetWriteCharacteristic, characteristic.properties.contains(.write) || characteristic.properties.contains(.writeWithoutResponse) else { print("Peripheral/Characteristic is nil or doesn't support writing") return } // Convert Int8 value to Data let data = Data(bytes: &value, count: MemoryLayout<Int8>.size) // Write to peripheral (use .withoutResponse if you don't need confirmation) peripheral.writeValue(data, for: characteristic, type: .withResponse) } }
3. Key Additional Checks
- Wait for proper initialization: Only enable the send button after the
CharacteristicReadynotification fires—this ensures the peripheral is connected and the characteristic is ready. - Verify UUIDs: Double-check that the service and characteristic UUIDs in your code match exactly what the Bluetooth peripheral is advertising. Mismatched UUIDs will prevent discovery.
- Check characteristic properties: Ensure the peripheral’s characteristic actually supports writing (look for
.writeor.writeWithoutResponsein its properties).
Debugging Tips
- Add print statements in
AppDelegate’s delegate methods to confirm when the peripheral connects and the characteristic is discovered. - In your
writeValuemethod, printperipheralandcharacteristicto confirm they’re not nil when the button is pressed. - Use Xcode’s debug navigator to inspect the state of
AppDelegate’s Bluetooth objects at runtime.
内容的提问来源于stack exchange,提问作者Nazia Islam
相关产品推荐
相关产品推荐

