iOS SDK
Native iOS input via TAPKit. Pair in Settings first — TAPKit does not scan.
- Package
- Install
- Hello Tap
- TAPKitDelegate
- TAPInputMode
- Combinations
- Haptics
- Raw sensors
- TapXR Spatial Control
- Logging
Package
| Source | TapWithUs/tap-ios-sdk |
|---|---|
| License | Apache 2.0 |
| Status | Official |
| Language | Swift (Obj-C supported) |
Install
Clone the repo and compile TAPKit.framework, then link it into your app.
import TAPKitHello Tap
Complete minimal delegate + start:
import UIKit
import TAPKit
class HelloTapViewController: UIViewController, TAPKitDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Device must already be paired in iOS Settings.
TAPKit.sharedKit.addDelegate(self)
TAPKit.sharedKit.start()
}
func tapConnected(withIdentifier identifier: String, name: String) {
print("connected:", name, identifier)
// Connected devices default to controller mode in TAPKit.
}
func tapDisconnected(withIdentifier identifier: String) {
print("disconnected:", identifier)
}
func tapped(identifier: String, combination: UInt8) {
let fingers = TAPCombination.toFingers(combination)
print("tap", combination, "fingers", fingers)
}
func moused(identifier: String, velocityX: Int16, velocityY: Int16, isMouse: Bool) {
guard isMouse else { return }
print("mouse", velocityX, velocityY)
}
}TAPKitDelegate
All methods are optional. Register with addDelegate:
@objc public protocol TAPKitDelegate : class {
@objc optional func tapConnected(withIdentifier identifier: String, name: String)
@objc optional func tapDisconnected(withIdentifier identifier: String)
@objc optional func tapFailedToConnect(withIdentifier identifier: String, name: String)
@objc optional func tapped(identifier: String, combination: UInt8)
@objc optional func moused(identifier: String, velocityX: Int16, velocityY: Int16, isMouse: Bool)
@objc optional func rawSensorDataReceived(identifier: String, data: RawSensorData)
@objc optional func tapChangedAirGesturesState(identifier: String, isInAirGesturesState: Bool)
@objc optional func tapAirGestured(identifier: String, gesture: TAPAirGesture)
@objc optional func tapDidReadHardwareVersion(identifier: String, hw: Int)
@objc optional func tapDidReadFirmwareVersion(identifier: String, fw: Int)
}TAPKit.sharedKit.addDelegate(self)
TAPKit.sharedKit.start()
// …
TAPKit.sharedKit.removeDelegate(self)Connected taps: TAPKit.sharedKit.getConnectedTaps() → dictionary of identifier → display name.
TAPInputMode
- Controller (default when connected via SDK) —
tapped/moused - Text — HID keyboard; SDK tap callbacks not called
- Controller with Mouse HID — controller + system mouse (AssistiveTouch cursor on iOS 13+)
- Raw Sensor — gyro / accelerometer stream
TAPKit.sharedKit.setTAPInputMode(TAPInputMode.text(), forIdentifiers: nil)
TAPKit.sharedKit.setTAPInputMode(TAPInputMode.controller(), forIdentifiers: nil)
TAPKit.sharedKit.setDefaultTAPInputMode(TAPInputMode.controller(), immediate: true)Combinations
combination is UInt8 in 1…31. Bit0 = thumb … bit4 = pinky. Example: 5 → thumb + middle.
let fingers = TAPCombination.toFingers(combination)Haptics
Up to 18 durations (ms) as haptic, pause, haptic, pause… Null/missing identifiers = all connected taps.
TAPKit.sharedKit.vibrate(durations: [500, 100, 500])Raw sensors
Five 3-axis finger accelerometers + thumb IMU (Tap Strap 2). Stream callback ~200/min.
TAPKit.sharedKit.setTAPInputMode(
TAPInputMode.rawSensor(sensitivity: TAPRawSensorSensitivity())
)
func rawSensorDataReceived(identifier: String, data: RawSensorData) {
if data.type == .Device {
if let thumb = data.getPoint(for: RawSensorData.iDEV_THUMB) {
print(thumb.x, thumb.y, thumb.z)
}
} else if data.type == .IMU {
if let gyro = data.getPoint(for: RawSensorData.iIMU_GYRO) {
print(gyro.x, gyro.y, gyro.z)
}
}
}TapXR Spatial Control
Extended air-gesture aggregation and input-type selection are experimental and limited to qualified developers on TapXR. Request access. XR air-gesture values 100–102 and TAPXRState are documented in the public README once you have access.
Logging
TAPKit.log.enableAllEvents()
TAPKit.log.enable(event: .error)
TAPKit.log.disableAllEvents()