Can't connect to AirPods via BLE

2019-03-25 10:54发布

问题:

I am trying to connect automatically to my AirPods with a simple app using BLE. I get the name of the device and the status to "connecting", but for some reason I can't connect to it. Function 'didConnect peripheral' is never triggered.

I tried all different approaches from tutorials and from other posts, tried to store the peripheral data in an array to keep the reference but nothing seem to work.

Is there any step which I can get some extra info between 'didDiscover' and 'didConnect'?

Working in XCode 9.2, using Swift 4 and iOS 11.2 on iPhone.

Here's my code:

let deviceName = "AirPods de Roger"
var isConnected = false

var manager: CBCentralManager!
var peripheralBLE: CBPeripheral?

override func viewDidLoad() {
    super.viewDidLoad()
    manager = CBCentralManager(delegate: self, queue: nil)
}

func centralManagerDidUpdateState(_ central: CBCentralManager) {
    switch manager.state {
    case.poweredOff:
        print("BLE service is powered off")
    case.poweredOn:
        print("BLE service is powered on and scanning")
        manager.scanForPeripherals(withServices: nil, options: nil)
    default:
        print("BLE service in another state")
    }
}

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
    if peripheral.name == deviceName && isConnected == false {
        self.manager.stopScan()
        self.peripheralBLE = peripheral
        self.peripheralBLE?.delegate = self
        manager.connect(peripheral, options: nil)
        isConnected = true
        print("\(peripheral.name) pre-connected")
    }
}

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    lblConnected.isHidden = false
    print("AirPods Connected")
    peripheral.discoverServices(nil)
}

回答1:

This one is my current implementation:

import UIKit
import CoreBluetooth

var manager: CBCentralManager!
var peripheralBLE: CBPeripheral!

class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
let deviceName = "AirPods de Iván"
var isConnected = false


@IBOutlet weak var Label: UILabel!
@IBAction func Click(_ sender: UIButton) {
    self.connect()
}

override func viewDidLoad() {
    super.viewDidLoad()
    manager = CBCentralManager(delegate: self, queue: nil)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func connect()  {
    manager.connect(peripheralBLE, options: nil)
    print("connect")
    self.updateLabelStatus()
}

func disconnect() {
    manager.cancelPeripheralConnection(peripheralBLE!)
    print("disconnect")
    self.updateLabelStatus()
}

func updateLabelStatus() {
    switch peripheralBLE.state {
    case.connected:
        Label.text = "connected"
    case.disconnected:
        Label.text = "disconnected"
    case.connecting:
        Label.text = "connecting"
    case.disconnecting:
        Label.text = "disconnecting"
    default:
        Label.text = "label"
    }
}

func centralManagerDidUpdateState(_ central: CBCentralManager) {
    switch manager.state {
    case.poweredOff:
        print("BLE service is powered off")
    case.poweredOn:
        print("BLE service is powered on and scanning")
        manager.scanForPeripherals(withServices: nil, options: nil)
    default:
        print("BLE service in another state")
    }
}

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
    if peripheral.name == deviceName && isConnected == false {
        print("found AirPods \(peripheral)")
        peripheralBLE = peripheral
        peripheralBLE!.delegate = self
        manager.stopScan()
        self.updateLabelStatus()
    }
}

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    print("AirPods Connected")
    peripheral.discoverServices(nil)
    self.updateLabelStatus()
}

func centralManager(_ central: CBCentralManager,
                    didFailToConnect peripheral: CBPeripheral,
                    error: Error?) {
    print("AirPods Connect error")
    print(error)
    self.updateLabelStatus()
}
}

I am finding the device but when I try to connect, nothing happens BLE service is powered on and scanning found AirPods <CBPeripheral: 0x1c4103f00, identifier = 0E6FCF72-B86E-FB10-DD62-4A575BAD0ECC, name = AirPods de Iván, state = disconnected> connect

  • I can connect other devices with this code
  • I can connect the airpods with my mac without problems with a similar code
  • I can't connect airpods with my iphone :S

Something strange happens here I am almost sure that the code is right



回答2:

Since the AirPods advertise with kCBAdvDataIsConnectable = 0, they're not supposed to be connected via BLE.