BeeTee

Demo application for Bluetooth device scanning using the iOS private framework "BluetoothManager"

199
35
Swift

Build Status
codebeat badge
codecov
MIT licensed

BeeTee

BeeTee is an easy to use Swift framework, that allows simple access to the Bluetooth classic in iOS for turning on/off and scanning for Bluetooth devices.

Besides BeeTee demonstrates how to access the private BluetoothManager.framework in iOS.

Table of Contents

Limitations

Based on the AppStore guideline §2.5 on private (undocumented) functions it is not possible to publish apps with the BeeTee and BluetoothManager.framework in the AppStore.

You need a valid membership of the iOS Developer Program, because the BeeTee does not work in the iOS simulator.

Connecting to devices is not possible in most cases and, therefore, not yet supported.

There are currently no known limitations on iOS versions.

Installation

Copy all files in the BeeTee folder to your project and done. That means there are 9 files to copy:

  • BluetoothDevice.h
  • BluetoothManager.h
  • BluetoothDeviceHandler.h
  • BluetoothDeviceHandler.m
  • BluetoothManagerHandler.h
  • BluetoothManagerHandler.m
  • BeeTee-Bridge-Header.h
  • BeeTee.swift
  • BeeTeeDevice.swift

Usage

Here is a small code snippet, how easily you can use BeeTee:

class Demo: BeeTeeDelegate {
    let beeTee = BeeTee()
    
   init() {
        beeTee.delegate = self
        beeTee.enableBluetooth()
        beeTee.startScanForDevices()
    }
    
    func receivedBeeTeeNotification(notification: BeeTeeNotification) {
        switch notification {
        case .DeviceDiscovered:
            for device in beeTee.availableDevices {
                print(device)
            }
        default:
            print(notification)
        }
    }
}

API

BeeTee

The API is based on the other hardware managers, such as CLLocationManager or the underlaying BluetoothManager.framework.

I focused on a clear distinction between the different layers, also by using different programming languages:

Layer architecture of BeeTee

BeeTeeNotification

public enum BeeTeeNotification {
    case PowerChanged
    case AvailabilityChanged
    case DeviceDiscovered
    case DeviceRemoved
    case ConnectabilityChanged
    case DeviceUpdated
    case DiscoveryStateChanged
    case DeviceConnectSuccess
    case ConnectionStatusChanged
    case DeviceDisconnectSuccess
    
    static let allNotifications: [BeeTeeNotification]
}

So all known notification from BluetoothManager.framework are passed through (see next section). I used only PowerChanged, DeviceDiscovered, DeviceRemoved in my demo application.

BeeTeeDelegate

public protocol BeeTeeDelegate {
    func receivedBeeTeeNotification(notification: BeeTeeNotification)
}

BeeTee

public class BeeTee {
	public var delegate: BeeTeeDelegate?
	public var availableDevices: [BeeTeeDevice]
	convenience init(delegate: BeeTeeDelegate)
	public func enableBluetooth()
	public func disableBluetooth()
	public func bluetoothIsEnabled() -> Bool
	public func startScanForDevices()
	public func stopScan()
	public func isScanning() -> Bool
	public static func debugLowLevel() // see section BluetoothManager.framework/Available Notification
}

BluetoothManager.framework

If you want to dive deeper into BluetoothManager.framework this section is interesting for you.

Available Notifications

I found the following notification regarding Bluetooth

BluetoothAvailabilityChangedNotification
BluetoothDiscoveryStateChangedNotification
BluetoothDeviceDiscoveredNotification
BluetoothDeviceRemovedNotification
BluetoothPowerChangedNotification
BluetoothConnectabilityChangedNotification
BluetoothDeviceUpdatedNotification
BluetoothDeviceConnectSuccessNotification
BluetoothConnectionStatusChangedNotification
BluetoothDeviceDisconnectSuccessNotification

Maybe the list is not complete. You can look for them yourself using

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
        nil,
        { (_, observer, name, _, _) in
            let n = name?.rawValue as! String
            if n.hasPrefix("B") { // notice only notification they are associated with the BluetoothManager.framework
                print("Received notification: \(name)")
            }
        },
        nil,
        nil,
        .deliverImmediately)

or with in BeeTee:

BeeTee.debugLowLevel()

Known Issues

If you have problems make this project running have a look at Stackoverflow. If you have other questions or suggestions, feel free to contact me here in GitHub or somehow else. 😃

Contributions

Help is welcome! If you do not know what to do, just pick one item and send me a pull request.

  • [ ] Fix issue with multiple notifications
  • [ ] Restructure BeeTee in a framework (BeeTee.framework, see discussion on stackoverflow)
  • [ ] Write test cases
  • [ ] Support Cocoapods
  • [ ] Improve documentation, especially inline documentation
  • [ ] Provide app icons
  • [x] Support Travis support

Versions

3.0

  • Rewritten in Swift 3
  • New API
  • Clear separation of Objective-C and Swift code
  • Dynamically loading of Bluetooth.framework (so no more header and import trouble)
  • Released now under MIT license

2.0

  • Wrapper classes MDBluetoothManager and MDBluetoothDevice introduced
  • Updated to ARC
  • Extented GUI

1.0

  • Initial Commit as demo project for BluetoothManager.framework, Non-ARC

License

BeeTee is released under the MIT license. See LICENSE for more details.
The list icon was created by Aya Sofya (thenounproject.com).