TAP

iOS SDK

Native iOS input via TAPKit. Pair in Settings first — TAPKit does not scan.

  1. Package
  2. Install
  3. Hello Tap
  4. TAPKitDelegate
  5. TAPInputMode
  6. Combinations
  7. Haptics
  8. Raw sensors
  9. TapXR Spatial Control
  10. Logging

Package

SourceTapWithUs/tap-ios-sdk
LicenseApache 2.0
StatusOfficial
LanguageSwift (Obj-C supported)

Install

Clone the repo and compile TAPKit.framework, then link it into your app.

Import
import TAPKit

Hello Tap

Complete minimal delegate + start:

HelloTapViewController.swift
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:

TAPKitDelegate
@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)
}
swift
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
swift
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.

swift
let fingers = TAPCombination.toFingers(combination)

Haptics

Up to 18 durations (ms) as haptic, pause, haptic, pause… Null/missing identifiers = all connected taps.

swift
TAPKit.sharedKit.vibrate(durations: [500, 100, 500])

Raw sensors

Five 3-axis finger accelerometers + thumb IMU (Tap Strap 2). Stream callback ~200/min.

swift
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

swift
TAPKit.log.enableAllEvents()
TAPKit.log.enable(event: .error)
TAPKit.log.disableAllEvents()