Pradeep Reddy Kypa
Pradeep Reddy Kypa

Reputation: 4022

How to know if a Bluetooth Device is Connected in iOS?

What is the best way to know on how a Bluetooth Device is already connected? I am using CBCentralManager to identify if the Bluetooth is Powered ON but I am unable to find out on how I can identify If a Bluetooth Device is already connected.

I am implementing routing of AVAudioSession Calls via a Connected Bluetooth device but AudioSession Category changes are getting called repeatedly due to which I am unable to find if a Bluetooth Device is connected or not. If anyone have tried to implement this behaviour, Your inputs might be helpful. Please share the information.

Upvotes: 0

Views: 1682

Answers (3)

David Feldman
David Feldman

Reputation: 9

use NotificationCenter

NotificationCenter.default.addObserver(
   self,
   selector: #selector(handleAudioSessionRouteChange(_:)),
   name: NSNotification.Name.AVAudioSessionRouteChange,
   object: nil)

    @objc private func handleAudioSessionRouteChange(_ notification: Notification) {
            guard let userInfo = notification.userInfo,
                  let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
                  let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else {return}
            switch reason {
            case .newDeviceAvailable:
                let session = AVAudioSession.sharedInstance()
                for output in session.currentRoute.outputs {
                    print("Bluetooth A2DP device connected: \(output.portName)")
                    self.speakerButton.setImage(UIImage(systemName: "s.circle.fill"), for: .normal)
                }
            case .oldDeviceUnavailable:
                if let previousRoute = userInfo[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription {
                    for output in previousRoute.outputs{
                        print("Bluetooth A2DP device disconnected: \(output.portName)")
                        self.speakerButton.setImage(UIImage(named: "speaker-button"), for: .normal)
                    }
                }
            default:
                break
            }
        }
        deinit {
            NotificationCenter.default.removeObserver(self)
        }

or you can use

    func checkBluetoothConnection() {
        let session = AVAudioSession.sharedInstance()
        let connectedBluetoothDevices = session.availableInputs?.filter { input in
            input.portType == .bluetoothHFP || input.portType == .bluetoothLE || input.portType == .bluetoothA2DP
        }
       isBluetoothConnected = connectedBluetoothDevices?.isEmpty == false
    }

the first option is when audio routes change.

the second option looks if a Bluetooth is connected even the AudioSession route did not change

Upvotes: -1

Rob Napier
Rob Napier

Reputation: 299663

The kind of Bluetooth your describing here is an audio device, which is almost certainly "classic" Bluetooth. This is unrelated to CoreBluetooth, which mostly handles GATT connections over BLE (along with some other, lesser-used protocols). You cannot find out anything about connected audio devices use CoreBluetooth.

To check your audio route, see AVAudioSesssion.currentRoute.outputs. The portType will tell you whether it's a Bluetooth device. Note that there are several types that may classify as "Bluetooth" for your purposes:

  • bluetoothA2DP: High quality music (unidirectional)
  • bluetoothHFP: Bidirectional (microphone/speaker) voice; low-quality
  • carAudio: CarPlay (non-CarPlay systems are either A2DP or HFP)
  • bluetoothLE: Hearing aids. While this is BLE, it's not part of CoreBluetooth.

Upvotes: 1

Lilya
Lilya

Reputation: 567

I am using CBPeripheral.state == .connected to check the state of the BLE device.

From the documentation:

/**
 *  @enum CBPeripheralState
 *
 *  @discussion Represents the current connection state of a CBPeripheral.
 *
 */
@available(iOS 7.0, *)
public enum CBPeripheralState : Int {

    
    case disconnected = 0

    case connecting = 1

    case connected = 2

    @available(iOS 9.0, *)
    case disconnecting = 3
}

Upvotes: 0

Related Questions