레퍼런스
BhapticsKit 클래스는 Swift에서 bHaptics 햅틱 디바이스를 제어하는 함수를 제공합니다. 햅틱 디바이스 연결, 햅틱 패턴 재생, 디바이스 모터의 직접 제어, 햅틱 재생 관리를 할 수 있습니다.
import BhapticsPlugin
let kit = BhapticsKit()
햅틱을 재생하는 함수는 요청 ID를 반환합니다. 이를 사용하여 재생 상태를 확인하거나 재생을 중지할 수 있습니다.
라이프사이클
init
init()
init(delegate: BhapticsKitDelegate?)
SDK 인스턴스를 생성합니다. 인스턴스는 하나만 생성하고 앱이 실행되는 동안 유지하세요.
iOS와 visionOS에서는 인스턴스를 생성하면 Bluetooth가 시작되며, 시스템이 사용자에게 Bluetooth 권한을 요청합니다.
매개변수
delegate(선택): Bluetooth 및 디바이스 상태 변화를 수신합니다. BhapticsKitDelegate를 참고하세요.
initialize
func initialize(appId: String, apiKey: String, defaultSetting: String) async -> Bool
func initialize(appId: String, apiKey: String, defaultSetting: String)
햅틱 환경을 초기화합니다. 이 함수는 이벤트 관련 함수를 사용하기 전에 호출해야 합니다.
- iOS와 visionOS에서는 서버에서 햅틱 앱의 햅틱 이벤트를 다운로드합니다.
- macOS에서는 bHaptics Player에 연결합니다. bHaptics Player가 설치되어 있지만 실행 중이 아니라면 bHaptics Player를 실행합니다.
async가 아닌 버전은 같은 초기화를 백그라운드에서 수행하며, 결과를 반환하지 않습니다.
매개변수
appId: bHaptics Developer Portal에서 생성한 애플리케이션 ID.apiKey: bHaptics Developer Portal에서 생성한 API 키.defaultSetting: 빈 문자열("")을 전달합니다.
반환값
초기화 성공 여부.
예제
let result = await kit.initialize(appId: "your_app_id", apiKey: "your_api_key", defaultSetting: "")
print("Initialization result: \(result)")
delegate
var delegate: BhapticsKitDelegate?
Bluetooth 및 디바이스 상태 변화를 수신합니다. BhapticsKitDelegate를 참고하세요.
이벤트 기반 햅틱 재생
특정 이벤트에 바인딩된 햅틱 패턴(bHaptics Designer/Portal에서 디자인)을 재생합니다. 대부분의 애플리케이션에 권장되는 함수입니다.
play
func play(eventId: String) -> Int
미리 정의된 햅틱 이벤트를 재생합니다.
매개변수
eventId: 햅틱 이벤트의 이름.
반환값
요청 ID. 재생을 중지하는 데 사용할 수 있습니다.
예제
let requestId = kit.play(eventId: "heartbeat")
print("Playback request ID: \(requestId)")
playParam
func playParam(
eventId: String,
requestId: Int? = nil,
intensity: Float,
duration: Float,
angleX: Float,
offsetY: Float
) -> Int
햅틱의 강도, Duration, 방향을 조정하여 햅틱 이벤트를 재생합니다.
매개변수
eventId: 햅틱 이벤트의 이름.requestId(선택): 이 재생에 사용할 요청 ID. 생략하면 임의의 ID가 할당됩니다.intensity: 햅틱 Intensity 배율. 유효 범위: [0.0-2.0] (기본값:1.0)duration: Duration 배율. (기본값:1.0)angleX: 햅틱을 반시계 방향으로 회전합니다. 유효 범위: [0.0-360.0] (기본값:0.0)offsetY: 햅틱을 위 또는 아래로 이동합니다. 유효 범위: [-0.5-0.5] (기본값:0.0)
반환값
요청 ID. 재생을 중지하는 데 사용할 수 있습니다.
예제
let requestId = kit.playParam(eventId: "pistol_r", intensity: 1.0, duration: 1.0, angleX: 0.0, offsetY: 0.0)
playLoop
func playLoop(
eventId: String,
intensity: Float,
duration: Float,
angleX: Float,
offsetY: Float,
interval: Int,
maxCount: Int
) -> Int
햅틱 이벤트를 반복 재생합니다.
매개변수
eventId: 햅틱 이벤트의 이름.intensity: 햅틱 Intensity 배율. 유효 범위: [0.0-2.0] (기본값:1.0)duration: Duration 배율. (기본값:1.0)angleX: 햅틱을 반시계 방향으로 회전합니다. 유효 범위: [0.0-360.0] (기본값:0.0)offsetY: 햅틱을 위 또는 아래로 이동합니다. 유효 범위: [-0.5-0.5] (기본값:0.0)interval: 반복 사이의 시간 간격(밀리초).maxCount: 반복 횟수.
반환값
요청 ID. 재생을 중지하는 데 사용할 수 있습니다.
예제
let requestId = kit.playLoop(eventId: "heartbeat", intensity: 0.8, duration: 1.0, angleX: 90, offsetY: 0, interval: 150, maxCount: 5)
playWithStartTime
func playWithStartTime(
eventId: String,
startMillis: Int,
intensity: Float,
duration: Float,
angleX: Float,
offsetY: Float
) -> Int
햅틱 이벤트를 특정 시점부터 재생합니다. 이미 재생 중인 미디어와 햅틱을 동기화할 때 사용하세요.
매개변수
eventId: 햅틱 이벤트의 이름.startMillis: 재생 시작 시간. 이벤트 시작 시점부터 밀리초 단위로 측정합니다.intensity: 햅틱 Intensity 배율. 유효 범위: [0.0-2.0] (기본값:1.0)duration: Duration 배율. (기본값:1.0)angleX: 햅틱을 반시계 방향으로 회전합니다. 유효 범위: [0.0-360.0] (기본값:0.0)offsetY: 햅틱을 위 또는 아래로 이동합니다. 유효 범위: [-0.5-0.5] (기본값:0.0)
반환값
요청 ID. 재생을 중지하는 데 사용할 수 있습니다.
예제
// Start from 1.5 seconds into the event.
let requestId = kit.playWithStartTime(eventId: "music_video", startMillis: 1500, intensity: 1.0, duration: 1.0, angleX: 0, offsetY: 0)
playWithoutResult
func playWithoutResult(eventId: String, intensity: Float, duration: Float, angleX: Float, offsetY: Float)
요청 ID를 반환하지 않고 햅틱 이벤트를 재생합니다(fire-and-forget).
매개변수
eventId: 햅틱 이벤트의 이름.intensity: 햅틱 Intensity 배율. 유효 범위: [0.0-2.0] (기본값:1.0)duration: Duration 배율. (기본값:1.0)angleX: 햅틱을 반시계 방향으로 회전합니다. 유효 범위: [0.0-360.0] (기본값:0.0)offsetY: 햅틱을 위 또는 아래로 이동합니다. 유효 범위: [-0.5-0.5] (기본값:0.0)
예제
kit.playWithoutResult(eventId: "heartbeat", intensity: 0.8, duration: 1.0, angleX: 90, offsetY: 0.25)
햅틱 직접 재생
이벤트 없이 햅틱을 재생하려면 이 함수들을 사용하세요.
position은 다른 bHaptics SDK와 공통으로 사용하는 Int 값입니다. BhapticsPosition.index를 사용하여 얻을 수 있습니다. BhapticsPosition을 참고하세요.
playDot
@discardableResult
func playDot(position: Int, durationMillis: Int, arr: [Int]) -> Int
특정 햅틱 액추에이터에서 햅틱 피드백을 재생합니다.
매개변수
position: 재생할 햅틱 디바이스의 타입. 자세한 내용은 여기를 참고하세요.값 디바이스 모터 수 0TactSuit Pro 32 1TactSleeve(Left) 3 2TactSleeve(Right) 3 3TactVisor 4 4Tactosy for Hands(Left) 3 5Tactosy for Hands(Right) 3 6Tactosy for Feet(Left) 3 7Tactosy for Feet(Right) 3 8TactGlove(Left) 8 9TactGlove(Right) 8 durationMillis: 햅틱의 Duration(밀리초 단위).100이상을 권장합니다.arr: 배열의 길이를 디바이스의 모터 수에 맞게 지정합니다. 배열의 값은 모터의 Intensity를 의미합니다. 배열의 각 값에 대한 유효 범위: [0-100]
반환값
요청 ID. 재생을 중지하는 데 사용할 수 있습니다.
예제
// Sequentially activate 32 motors
let motorsCount = 32
for i in 0..<motorsCount {
var motors = [Int](repeating: 0, count: motorsCount)
motors[i] = 50
kit.playDot(position: BhapticsPosition.Vest.index, durationMillis: 500, arr: motors)
try await Task.sleep(nanoseconds: 500_000_000)
}
playPath
@discardableResult
func playPath(position: Int, durationMillis: Int, x: [Float], y: [Float], intensity: [Int]) -> Int
특정 좌표 주변에서 햅틱을 재생합니다. 각 햅틱 액추에이터의 햅틱 Intensity를 개별적으로 지정하는 playDot 함수와 달리, 이 메서드는 특정 좌표에 대한 햅틱 Intensity를 지정합니다.
햅틱 위치를 지정할 때 playDot은 이산적인 제어를 제공하는 반면, playPath는 더 연속적입니다. playDot은 개별 액추에이터에 Intensity를 할당하는 반면, playPath는 특정 좌표(X축과 Y축 모두 0과 1 사이)에 대한 Intensity 지정이 가능하며, 주변 액추에이터가 그에 따라 진동합니다.
여러 좌표와 여러 Intensity를 함께 지정할 수 있습니다. 배열에 있는 이 좌표들 주변의 모든 액추에이터는 순차적이 아니라 동시에(같은 시간에) 작동한다는 점에 유의하세요. 또한 모든 배열의 크기는 같아야 합니다.
값을 점진적으로 변경하면서 이 함수를 계속 호출하면 햅틱 포인트가 이동하는 효과를 구현할 수 있습니다.

매개변수
position: 재생할 햅틱 디바이스의 타입.playDot의 표를 참고하세요.durationMillis: 햅틱의 Duration(밀리초 단위).100이상을 권장합니다.x: 햅틱 이펙트의 X 좌표 배열. 각 값의 범위: [0.0-1.0]y: 햅틱 이펙트의 Y 좌표 배열. 각 값의 범위: [0.0-1.0]intensity: 각 좌표에 대한 Intensity 값 배열. 길이는 좌표의 수와 일치해야 합니다. 각 값의 범위: [0-100]
반환값
요청 ID. 재생을 중지하는 데 사용할 수 있습니다.
예제
// Path of point #1
let x1: [Float] = [0.738, 0.723, 0.709, 0.696, 0.682, 0.667, 0.653]
let y1: [Float] = [0.680, 0.715, 0.749, 0.782, 0.816, 0.852, 0.885]
// Path of point #2
let x2: [Float] = [0.061, 0.072, 0.102, 0.184, 0.254, 0.310, 0.363]
let y2: [Float] = [0.632, 0.587, 0.542, 0.498, 0.411, 0.366, 0.301]
for i in 0..<x1.count {
// Point #1 and #2 will vibrate at the same time.
kit.playPath(position: BhapticsPosition.Vest.index, durationMillis: 250, x: [x1[i], x2[i]], y: [y1[i], y2[i]], intensity: [20, 60])
try await Task.sleep(nanoseconds: 250_000_000)
}
playGlove
@discardableResult
func playGlove(position: Int, points: [GlovePoint], frequency: Int, repeatCount: Int) -> Int
TactGlove 전용. TactGlove에서 햅틱을 재생합니다. playDot을 사용할 때와 달리 햅틱 Duration과 진동 Intensity 변화를 세밀하게 조정할 수 있습니다. 이를 통해 햅틱 피드백을 더욱 디테일하게 표현할 수 있습니다.
작동시키려는 각 모터마다 GlovePoint를 전달합니다. 동작하려면 최소 하나의 포인트가 필요합니다.
struct GlovePoint {
var index: Int
var intensity: Int
var shape: Int
var playTime: Int
init(index: Int, intensity: Int, shape: Int = 0, playTime: Int = 0)
}
매개변수
-
position: 재생할 햅틱 디바이스의 타입.8또는9만 사용하세요.값 디바이스 8TactGlove(Left) 9TactGlove(Right) -
points:GlovePoint배열.-
index: 모터의 인덱스.인덱스 모터 위치 0엄지 끝 1검지 끝 2중지 끝 3약지 끝 4새끼손가락 끝 5손목 6손바닥 (엄지 쪽) 7손바닥 (새끼손가락 쪽) -
intensity: 모터의 Intensity. 유효 범위: [0-100] -
playTime: 작동 시간 간격.값 작동 시간 15ms 210ms 420ms 630ms 840ms -
shape: 시간에 따른 햅틱 Intensity 변화의 형태.값 파형 0Duration 동안 일정한 Intensity 1지정한 Intensity에서 시작하여 절반으로 감소 2지정한 Intensity의 절반에서 시작하여 지정한 Intensity까지 증가
-
-
frequency: 손목 모터의 진동 주파수(Hz). TactGlove DK3에만 적용됩니다. 기본값(80)을 사용하려면0을 전달하세요. -
repeatCount: 반복 횟수.
반환값
요청 ID. 재생을 중지하는 데 사용할 수 있습니다.
예제
let points = (0..<8).map { GlovePoint(index: $0, intensity: 100, shape: 2, playTime: 8) }
// Left hand
kit.playGlove(position: BhapticsPosition.GloveL.index, points: points, frequency: 0, repeatCount: 1)
// Right hand
kit.playGlove(position: BhapticsPosition.GloveR.index, points: points, frequency: 0, repeatCount: 1)
재생 제어
stopByRequestId
func stopByRequestId(_ requestId: Int)
요청 ID로 햅틱 재생을 중지합니다.
매개변수
requestId: 햅틱 재생 함수가 반환한 요청 ID.
예제
let requestId = kit.play(eventId: "shoot")
try await Task.sleep(nanoseconds: 2_000_000_000)
kit.stopByRequestId(requestId)
stopByEventId
func stopByEventId(_ eventId: String)
특정 이벤트 이름에 대한 모든 햅틱 재생을 중지합니다.
매개변수
eventId: 중지하려는 햅틱 이벤트의 이름.
stopAll
func stopAll()
현재 재생 중인 모든 햅틱을 중지합니다.
pause
func pause(_ eventId: String)
특정 이벤트의 재생을 일시 정지합니다.
매개변수
eventId: 일시 정지하려는 햅틱 이벤트의 이름.
resume
func resume(_ eventId: String)
일시 정지된 특정 이벤트의 재생을 재개합니다.
매개변수
eventId: 재개하려는 햅틱 이벤트의 이름.
turnOffMotors
func turnOffMotors()
연결된 모든 디바이스의 모터를 즉시 끕니다.
상태 확인
isPlaying
func isPlaying() -> Bool
전체 햅틱 재생 상태를 확인합니다. 이벤트 기반 재생과 직접 재생 모두에서 동작합니다.
isPlayingByRequestId
func isPlayingByRequestId(_ requestId: Int) -> Bool
특정 요청 ID의 재생 상태를 확인합니다. 이벤트 기반 재생과 직접 재생 모두에서 동작합니다.
isPlayingByEventId
func isPlayingByEventId(_ eventId: String) -> Bool
특정 이벤트의 재생 상태를 확인합니다.
getEventList
func getEventList() -> [String]
햅틱 앱에 있는 햅틱 이벤트의 이름을 반환합니다. 목록은 initialize가 완료된 후에 사용할 수 있습니다.
디바이스 관리
iOS와 visionOS에서는 SDK가 Bluetooth LE로 햅틱 디바이스를 스캔하고 연결합니다. macOS에서는 bHaptics Player가 디바이스를 관리합니다. 스캔 및 페어링 함수는 아무런 효과가 없으며, getDevices와 ping은 bHaptics Player에 연결된 디바이스를 대상으로 동작합니다.
scan
func scan()
주변의 bHaptics 디바이스 스캔을 시작합니다. 발견된 디바이스는 deviceStateUpdated로 전달됩니다. 페어링된 디바이스는 발견되면 자동으로 다시 연결됩니다.
스캔은 Bluetooth가 준비된 경우에만 시작됩니다. bleStateChange가 true를 알린 후에 호출하세요.
stopScan
func stopScan()
스캔을 중지합니다. 페어링되지도 연결되지도 않은 디바이스는 디바이스 목록에서 제거됩니다.
isScanning
func isScanning() -> Bool
SDK가 스캔 중인지 확인합니다.
toggleScanning
func toggleScanning() -> Bool
SDK가 스캔 중이면 스캔을 중지하고, 그렇지 않으면 스캔을 시작합니다.
반환값
호출 후 SDK가 스캔 중인지 여부.
pair
func pair(device: BhapticsDevice)
디바이스를 페어링하고 연결합니다. SDK는 앱을 다시 실행해도 페어링된 디바이스를 기억합니다.
매개변수
device: 페어링할 디바이스.getDevices또는deviceStateUpdated에서 얻을 수 있습니다.
unpair
func unpair(device: BhapticsDevice)
디바이스의 페어링을 해제하고 연결을 끊습니다.
매개변수
device: 페어링을 해제할 디바이스.
getDevices
func getDevices() -> [BhapticsDevice]
발견되거나 페어링된 디바이스를 반환합니다. BhapticsDevice를 참고하세요.
ping
@discardableResult
func ping(device: String) -> Bool
특정 디바이스에 핑을 보냅니다. 디바이스가 짧게 진동하므로 사용자가 디바이스를 식별할 수 있습니다.
매개변수
device: BhapticsDevice의uuid.
반환값
핑 전송 여부.
예제
if let device = kit.getDevices().first {
kit.ping(device: device.uuid)
}
pingAll
@discardableResult
func pingAll() -> Bool
연결된 모든 디바이스에 핑을 보냅니다.
반환값
핑 전송 여부.
getBluetoothState
func getBluetoothState() -> Int
Bluetooth 상태를 반환합니다. 디바이스가 발견되지 않는 이유를 파악할 때 사용하세요.
| 값 | 상태 |
|---|---|
0 | 알 수 없음 |
1 | 재설정 중 |
2 | 지원되지 않음 |
3 | 권한 없음 (Bluetooth 권한이 거부됨) |
4 | 꺼짐 |
5 | 켜짐 |
macOS 전용
isPlayerConnected
func isPlayerConnected() -> Bool
bHaptics Player와의 연결 상태를 확인합니다. iOS와 visionOS에서는 항상 false를 반환합니다.
onPlayerConnectionChanged
var onPlayerConnectionChanged: ((Bool) -> Void)?
bHaptics Player와의 연결 상태가 변경되면 메인 스레드에서 호출됩니다. macOS에서만 사용할 수 있습니다.
예제
#if os(macOS)
kit.onPlayerConnectionChanged = { connected in
print("bHaptics Player connected: \(connected)")
}
#endif
타입
BhapticsKitDelegate
protocol BhapticsKitDelegate {
func bHapticsKit(_ kit: BhapticsKit, bleStateChange state: Bool)
func bHapticsKit(_ kit: BhapticsKit, deviceStateUpdated devices: [BhapticsDevice])
func bHapticsKit(_ kit: BhapticsKit, didConnect device: BhapticsDevice)
func bHapticsKit(_ kit: BhapticsKit, didDisconnect device: BhapticsDevice)
}
iOS와 visionOS에서 Bluetooth 및 디바이스 상태 변화를 수신합니다.
bleStateChange: Bluetooth가 준비되었거나(true) 사용할 수 없게 되었습니다(false).deviceStateUpdated: 디바이스 목록이 변경되었습니다. 디바이스가 발견, 페어링, 페어링 해제, 연결, 연결 해제될 때 호출됩니다.didConnect: 디바이스가 연결되었습니다.didDisconnect: 페어링되지 않은 디바이스의 연결이 해제되었습니다.
BhapticsDevice
SDK가 발견한 햅틱 디바이스입니다.
| 속성 | 타입 | 설명 |
|---|---|---|
name | String | 디바이스의 이름. |
uuid | String | 디바이스의 고유 식별자. id로도 사용할 수 있습니다. |
position | PositionType | 디바이스를 착용하는 신체 부위. |
battery | Int | 배터리 잔량(퍼센트). 알 수 없으면 -1. |
connected | Bool | 디바이스의 연결 여부. |
paired | Bool | 디바이스의 페어링 여부. |
BhapticsPosition
햅틱 디바이스의 타입입니다. playDot, playPath, playGlove 등의 함수에 전달하려면 index를 사용하세요.
| 케이스 | index | 디바이스 |
|---|---|---|
.Vest | 0 | TactSuit |
.ForearmL | 1 | TactSleeve(Left) |
.ForearmR | 2 | TactSleeve(Right) |
.Head | 3 | TactVisor |
.HandL | 4 | Tactosy for Hands(Left) |
.HandR | 5 | Tactosy for Hands(Right) |
.FootL | 6 | Tactosy for Feet(Left) |
.FootR | 7 | Tactosy for Feet(Right) |
.GloveL | 8 | TactGlove(Left) |
.GloveR | 9 | TactGlove(Right) |
let position = BhapticsPosition.GloveL.index // 8