phnmnn
phnmnn

Reputation: 13250

iOS 13 - How to check if user has accepted Bluetooth permission?

As part of iOS 13’s, apps now need to request permission if they want to access Bluetooth. enter image description here

How to check if user has accepted Bluetooth permission?

Upvotes: 16

Views: 24988

Answers (5)

Joshua Hart
Joshua Hart

Reputation: 852

Swift 5 IOS 13: based of accepted answer, but handles the peripheral connection type as well:

    enum BluetoothConnectionType {
        case central, peripheral
    }

    func isBluetoothAuthorized(forType type: BluetoothConnectionType) -> Bool {
        switch type {
        case .central:
            if #available(iOS 13.1, *) { return CBCentralManager.authorization == .allowedAlways }
            if #available(iOS 13.0, *) { return CBCentralManager().authorization == .allowedAlways }
            return true
        case .peripheral:
            if #available(iOS 13.1, *) { return CBPeripheralManager.authorization == .allowedAlways }
            if #available(iOS 13.0, *) { return CBPeripheralManager.authorizationStatus() == .authorized }
            return true
        }
    }

Upvotes: 9

NeverwinterMoon
NeverwinterMoon

Reputation: 2451

It's interesting that starting iOS 13.1 it's possible to check the BT permission without allocating CBManager. Which is a huge advantage, as initializing CBManager will automatically trigger the system pop-up in case BT permission was not asked/given before.

func checkPermission() -> CBManagerAuthorization {
    if #available(iOS 13.1, *) {
        return checkPermissionBeforeCBManagerAllocation()
    } else {
        return checkPermissionLegacy()
    }
}

@available(iOS 13.1, *)
private func checkPermissionBeforeCBManagerAllocation() -> CBManagerAuthorization {
    CBCentralManager.authorization
}

private func checkPermissionLegacy() -> CBManagerAuthorization {
    let manager = CBCentralManager(delegate: self, queue: nil)
    return manager.authorization
}

The above is just an example for iOS 13.x versions and doesn't handle anything below that.

Upvotes: 8

al_mota
al_mota

Reputation: 471

Try this:

var isBluetoothPermissionGranted: Bool {
    if #available(iOS 13.1, *) {
        return CBCentralManager.authorization == .allowedAlways
    } else if #available(iOS 13.0, *) {
        return CBCentralManager().authorization == .allowedAlways
    }
    
    // Before iOS 13, Bluetooth permissions are not required
    return true
}

Upvotes: 32

patel dhruval
patel dhruval

Reputation: 1052

Here is what I would use(Complete Solution for all iOS): Swift 5

class MainViewController: UIViewController {
    var isiOSBluetoothOn = false
       
    @IBAction func onBluetoothButtonClicked(_ sender: Any){
        if (isiOSBluetoothOn) {
            let newVC = self.storyboard?.instantiateViewController(withIdentifier: "blevc")
            self.navigationController?.pushViewController(newVC!, animated: true)
        } else {
            if #available(iOS 13.0, *) {
                if (CBCentralManager().authorization != .allowedAlways) {   //System will automatically ask user to turn on iOS system Bluetooth if this returns false
                   openAppOrSystemSettingsAlert(title: "Bluetooth permission is currently disabled for the application. Enable Bluetooth from the application settings.", message: "")
                }
            } else {
                let appName = Bundle.main.infoDictionary?["CFBundleName"] as? String
                openAppOrSystemSettingsAlert(title: "\"\(appName ?? "You Application Nam")\" would like to use Bluetooth for new connections", message: "You can allow new connections in Settings")
            }
        }
    }
                
    func openAppOrSystemSettingsAlert(title: String, message: String) {
        let alertController = UIAlertController (title: title, message: message, preferredStyle: .alert)
        let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in
            guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return }
            if UIApplication.shared.canOpenURL(settingsUrl) {
                UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                    print("Settings opened: \(success)") // Prints true
                })
            }
        }
        alertController.addAction(settingsAction)
        let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
        alertController.addAction(cancelAction)
        present(alertController, animated: true, completion: nil)
    }
}

extension MainViewController: CBCentralManagerDelegate {
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch central.state {
        case .poweredOn:
           isiOSBluetoothOn = true
            break
        case .poweredOff:
           isiOSBluetoothOn = false
            break
        default:
            break
        }
    }
}

Upvotes: -1

rmaddy
rmaddy

Reputation: 318854

CBCentralManager extends CBManager. As of iOS 13, CBManager has an authorization property.

Use this property to determine whether permission is unknown, allowed, denied, or restricted.

To be clear, under iOS, you need to use the instance property authorization, not the type property of the same name. Be sure you access authorization on an instance of CBCentralManager.

Upvotes: 14

Related Questions