Swift
, Combine
, CoreML
, and SwiftUI
.Combine
Framework
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 |
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