This library can collect various device and user data, forwarding it to a specified endpoint. The following data collectors are bundled with this version:
- Accelerometer
- Battery status
- Bluetooth LE devices connected / peered
- Approximate and precise location
- Gravity
- Gyroscope
- Indirect pointer (mouse)
- Magnetometer
- Pencil and stylus
- Pinch gesture
- Raw touch
- Swipe gesture
- Tap gesture
- WiFi connection and available networks
You can check out the Example app for a working example
import Trap
import SwiftUI
@main
struct ExampleApp: App {
let trapManager: TrapManager
var body: some Scene {
WindowGroup {
ContentView()
}
}
public init() {
/// Create a new configuration instance.
var config = TrapConfig()
/// Change what you need to change
config.reporter.interval = .seconds(3)
/// Set either a websocket endpoint...
config.reporter.url = "wss://example.com/api/ws"
/// ...or a HTTP POST endpont.
config.reporter.url = "https://example.com/api/post"
trapManager = TrapManager(withConfig: config)
// Run all default collectors...
trapManager.runAll()
// ...or use it one collector at a time
let collector = TrapPreciseLocationCollector(withConfig: config)
/// Check if the build-time conditions are ready for the collector
if collector.checkConfiguration() {
/// Check if the runtime permissions are given.
if !collector.checkPermission() {
/// Request the permission if you need to
collector.requestPermission { [self] in trapManager.run(collector: collector) }
} else {
/// ...or run the collector immediately.
trapManager.run(collector: collector)
}
}
}
}
You can add and remove custom metadata (a string key-value pair), that will be sent to the server periodically as part of the metadata event.
Adding metadata:
trapManager.addCustomMetadata(key: "some-key", value: "some-value")
Removing metadata:
trapManager.removeCustomMetadata(key: "some-key")
You can add a custom event to the event stream as well. This can contain simple types (string, numeric, boolean) and complex types (dictionaries and arrays of these types) as well.
trapManager.addCustomEvent(custom: DataType.dict([
"some-key": DataType.string("some-data"),
"numeric-data-key": DataType.int(2),
"boolean-data-key": DataType.bool(false)
]))
Many of the available data collectors require app bundle records (Info.plist) and/or entitlemens. Some of them needs Apple's special approval. Below are the details for each collector:
The only requirement is to have the bundle record 'NSMotionUsageDescription' defined and filled in.
The only requirement is to have the bundle record 'NSBluetoothAlwaysUsageDescription' defined and filled in. Requires runtime permission from the user.
The following bundle records need to be set:
- NSLocationAlwaysAndWhenInUseUsageDescription
- NSLocationWhenInUseUsageDescription
- NSLocationWhenInUseUsageDescription
- NSLocationUsageDescription
Requires runtime permission from the user.
The following entitlements needed for full operation:
- com.apple.developer.networking.HotspotHelper
- com.apple.developer.networking.wifi-info
The HotspotHelper entitlement can only be acquired if Apple approves your application (available at Apple HotspotHelper Request).
The core of the library is the TrapManager class. It manages the individual colllectors, which are available to the end developer. The other aspect is the data frame transport system, which is an endlessly repeating task with a configurable interval. The reporting task sends the data packets to the specified endpoint. The connection between the two aspects is a memory data store, which is implemented via a custom ring queue.
The goal of the implementation is low and predictably flat resource usage. Therefore on the critical UI path we attempted to avoid allocation and processing as much as possible. The processing part is mostly happening on a background thread. For this we use OperationQueues.
Many of the data types collected by this library is capable of identifying the individual user, therefore the integrating app can be affected by GDPR and/or CCPA. You are solely responsible for the data collected and processed via this library.
Licensed under the MIT license.