Swift, Combine, CoreML , and SwiftUI .CombineFramework
This SDK abstracts Core and our MetaWear C/C++ API using concise Combine publishers and presets. It offers three optional imports:
Meta — track groups of MetaWears across Apple devices using iCloud key-value storage
Meta — mix our C/C++ API with Combine publishers for additional flexibility
Meta — update firmware over Bluetooth

Beyond this guide, you can ramp up with an interactive From Zero to Machine Learning tutorial to build a simple app, similar to our barebones integration test host app. Existing MetaWear developers can orient with Migrating from the Bolts SDK. You can also examine the source code of our cross-platform MetaBase app.
For each target in your project, go to the Signing & Capabilities tab. For macOS, go to App Sandbox and check Bluetooth. For iOS, add Background Modes and check Uses Bluetooth LE accessories.
Optionally, for Meta, add iCloud and check Key value storage. If your plan to update MetaWear firmware in your app using Meta, for macOS in App Sandbox check Outgoing Connections.
For all platforms, go to the Info tab and add and provide a message for:
Privacy - Bluetooth Always Usage Description
Privacy - Bluetooth Peripheral Usage Description
Create a Meta instance or use the shared singleton.
Goal | API |
|---|---|
Search | |
Stop searching | |
Individual discovery events | |
Refreshing dictionary of devices | |
Bluetooth power and authorization |
A restored device may not be nearby right now, but was connected in a previous session. As with all MetaWear interactions, you’ll receive updates on that scanner’s ble.
If you wish to sync MetaWear identities via iCloud, only use the scanner to start/stop scanning and observe Bluetooth state. Use the Meta to retrieve, remember, and forget MetaWears. It will monitor the scanner’s output for you.
First, to connect to a MetaWear, call connect() or use the connect. You can observe connection state via the connection.
Since nearly every MetaWear interaction is an asynchronous call and response over a potentially low strength Bluetooth connection, this SDK reasons about these events and streams of data through Apple’s Combine framework. If unfamiliar with Combine, the From Zero to Machine Learning tutorial has some basics. A good reference is Joseph Heck’s Using Combine.
Most of this SDK’s functions extend Combine publishers that emit a MetaWear.
Fires | API |
|---|---|
On every connection | |
First connection only |
|
On every disconnection | |
Now, failing if not connected | |
Now |
From those publishers, autocompletion will reveal MetaWear operators.
Operator | Example |
|---|---|
| |
| |
| |
| |
| Returns |
metawear
.publishWhenConnected()
.first()
.stream(.accelerometer(rate: .hz100, range: .g2)
.map { makePrettyDataPoint($0) }
.receive(on: DispatchQueue.main)
.sink { [weak self] data in
self?.pretty.append(data)
}
.store(in: &subs)
metawear.connect()To chain logging or other commands, you can use .optionally and/or .macro(execute.
To stream an arbitrary number of sensors, you can setup individual pipelines, perhaps coordinated by prefix(until. You could also convert the myriad MWStreamable outputs to the same type, such as MWData, and form an array of publishers consumable by Combine’s Merge.
Beware that Bluetooth Low Energy usually can’t deliver above 100 Hz without dropping some data. Also, the prefix(until operator must output on the ble to avoid undefined behavior.
For logging, you can program a MetaWear to fire an onboard timer to poll a signal (direct from sensor or after some data processing) or fire an event after some trigger.
Operator | Output Reference Pointer | Input |
|---|---|---|
| Data signal embedded in the timer | Publisher<(MetaWear, MWDataSignal)> |
| Timer | Publisher<(MetaWear, MWDataSignal)> |
| Event timer | Publisher and a closure of commands to execute upon firing |
An MWData is a type alias for Opaque, which is simply a reference to a C type not exposed to Swift.
Bytes transmitted over Bluetooth and other MetaWear actions can be viewed using the MWConsole. Just assign a reference to that logger to a MetaWear’s log property.
Sometimes an incomplete or incorrect command can put a MetaWear in a bad state, which will crash when you reconnect. If reseting the device via unit test our apps fails, manually reset by connecting the MetaWear to power at the same time as pressing the mechanical button for 10 seconds.
Unit test targets can call on a host app that exposes a MetaWearScanner, but XCTest cannot instantiate its own MetaWearScanner with Bluetooth permission on its own.
UI test targets may also improperly parse Swift Package Manager dependencies. (If encountered, please file feedback with Apple.)
Swift, Combine, CoreML , and SwiftUI .MWPublisher ensures calls into the C++ library and reads of any properties occur on the bleQueue .class MetaWearScanner bleQueue .class MetaWear enum MWError typealias MWPublisher .command(), .log(), .read(), and .stream() operators accept value types conforming to these protocols, which describe communication methods with the MetaWear.protocol MWCommand protocol MWCommandWithResponse protocol MWLoggable protocol MWPollable protocol MWReadable protocol MWReadableMerged protocol MWStreamable struct MWFrequency SIMD3<Float>. Logs download in a string-based MWDataTable that can output a .csv file.struct MWDataTable struct MWData protocol MWDataConvertible MblMwData C++ struct into a defined Swift value type whose lifetime is not confined to the C++ closure.typealias Download struct MWAmbientLight struct MWBuzzer struct MWHapticMotor struct MWThermometer struct MWStepCounter struct MWStepDetector struct MWBatteryLevel struct MWChargingStatus struct MWChangeAdvertisingName struct MWLastResetTime struct MWLogLength struct MWMACAddress info property exposes the stable MAC address.struct MWMacro enum MWNamedSignal struct MWFactoryReset struct MWActivitiesReset struct MWRestart class MWConsoleLogger activateConsoleLoggingOnAllMetaWears to enroll all devices or manually set the logger in the target MetaWear.protocol MWConsoleLoggerDelegate info contains a stable MAC address.typealias CBPeripheralIdentifier typealias MACAddress func bridge<T>(obj: T) -> UnsafeMutableRawPointer func bridge<T>(ptr: UnsafeRawPointer ) -> T func bridgeRetained <T>(obj: T) -> UnsafeMutableRawPointer func bridgeTransfer <T>(ptr: UnsafeRawPointer ) -> T OpaquePointer or an integer identifier.typealias MWBoard typealias MWDataSignal MblMwDataSignal typealias MWDataSignalOrBoard typealias MWDataProcessorSignal typealias MWLoggerSignal typealias MWTimerSignal typealias MWMacroIdentifier enum MWStatusCode enum MWComparatorOption