Skip to content

codeinversion/sensors-swift

Repository files navigation

Swifty Sensors

iOS macOS Swift 3.0 License CocoaPods

Bluetooth LE Sensor Manager for iOS and macOS.

Full API Documentation

Installation

CocoaPods

use_frameworks!
pod 'SwiftySensors'

Manual

Copy all of the swift files in the Sources directory into you project.

Swift Package Manager

Add this repo url to your dependencies list:

dependencies: [
    .Package(url: "https://github.com/kinetic-fit/sensors-swift", Version(X, X, X))
]

Note: If you are using the Swifty Sensors Kinetic Plugin, you cannot use the Swift Package Manager at this time due to no support for objective-c libraries.

Usage

See the Example iOS App for a basic example of:

  • scanning for sensors
  • connecting to sensors
  • discovering services
  • discovering characteristics
  • reading values
  • characteristic notifications

Initialization of a SensorManager is straightforward.

  1. Set the services you want to scan for
  2. Add additional services you want to discover on sensor (but not scan for in advertisement data)
  3. Set the scan mode of the manager
// Customize what services you want to scan for
SensorManager.instance.setServicesToScanFor([
    CyclingPowerService.self,
    CyclingSpeedCadenceService.self,
    HeartRateService.self
])

// Add additional services we want to have access to (but don't want to specifically scan for)
SensorManager.instance.addServiceTypes([DeviceInformationService.self])

// Set the scan mode (see documentation)
SensorManager.instance.state = .aggressiveScan

// Capture SwiftySensors log messages and print them to the console. You can inject your own logging system here if desired.
SensorManager.logSensorMessage = { message in
    print(message)
}

SwiftySensors uses Signals to make observation of the various events easy.

// Subscribe to Sensor Discovery Events
SensorManager.instance.onSensorDiscovered.subscribe(on: self) { sensor in
    // sensor has been discovered (but not connected to yet)
}

// Subscribe to value changes on a Characteristic
characteristic.onValueUpdated.subscribe(on: self) { characteristic in
    // characteristic.value was just updated
}

All Services and Characteristics are concrete classes to make working with Bluetooth LE sensors much easier.

Example Heart Rate Sensor Hierarchy:

Sensor
    - HeartRateService
        - Measurement
        - BodySensorLocation
    - DeviceInformationService
        - SoftwareRevision
        - ModelNumber
        - SerialNumber
        - ...

To connect to a Sensor:

SensorManager.instance.connectToSensor(sensor)

Subscribing to value updates and getting the deserialized value of a Heart Rate Sensor:

// The sensor could be selected by a user, selected by a matching algorithm on the sensor's advertised services, etc.
let sensor = < Heart Rate Sensor >

// The function service() on a sensor will try to find the appropriate return type requested
guard let hrService: HeartRateService = sensor.service() else { return }

// The function characteristic() on a service will try to find the appropriate return type requested
guard let hrMeasurement: HeartRateService.Measurement = hrService.characteristic() else { return }
// ... the HeartRateService class also defines the `measurement` property, which is equivalent to the above

hrMeasurement.onValueUpdated.subscribe(on: self) { characteristic in
    // The Measurement characteristic has a deserialized value of the sensor data
    let heartRate = hrMeasurement.currentMeasurement.heartRate    
}

Current Concrete Services and Characteristics

Extensions and 3rd Party Services

Injecting Types; Writing Services, Characteristics, Extensions

Adding custom functionality specific to your needs is fairly straightforward.

// Customize the Sensor class that the manager instantiates for each sensor
SensorManager.instance.SensorType = < Custom Sensor Class : Extends Sensor >

Look at HeartRateService for a simple example of writing your own Service class.

To add new Characteristic types to an existing Service that is not a part of the official spec, take a look at the Wahoo Trainer Characteristic Extension. This is NOT a normal solution adopted by BLE sensor manufaturers, but occassionally they break the rules.

Serializers

The serialization / deserialization of characteristic data is isolated outside of the Characteristic classes and can be used alone. This can be useful if you already have a Sensor management stack and just need the logic to correctly deserialize various BLE messages.

use_frameworks!
pod 'SwiftySensors/Serializers'

Known bugs

None.

ToDos

There are many official BLE specs that need to be implemented.

Projects Using SwiftySensors

Let us know if you want your App listed here!

Full API Documentation