Swifty Sensors
Bluetooth LE Sensor Manager for iOS and macOS.
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.
- Set the services you want to scan for
- Add additional services you want to discover on sensor (but not scan for in advertisement data)
- 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
- Wahoo Trainer Characteristic Extension for the Cycling Power Service
- Kinetic Sensors
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!