iOS13で公開予定の「Core Haptics」を使って、Haptic Feedback (触覚フィードバック) するコードを書いてみた
こんにちは。iOS エンジニアの森廣です。
先日行われたAppleのWWDC2019に参加させていただいたことをきっかけに、最新技術を追いかける楽しさに目覚めました。
今回は、その最新技術の中でも自社サービスに取り込めそうな技術を、実際のコードとともに紹介したいと思います。
Haptic Feedback とは
Haptic Feedback とは、ユーザーアクションに対してハードウェアを振動させる触覚フィードバックのことです。
例で言うと、App Storeでアプリを購入する時、間違ったパスワードを入力した時などに発生する振動が「Haptic Feedback」にあたります。
Haptic Feedback を導入するメリットとしては、ユーザーにより自然な感覚を与えられることで、没入感を高められることです。
(特にゲームやVR/AR領域での活用が見込めるかと思います。)
iOS10からは UIFeedbackGenerator を利用することで3種類のフィードバックを導入できましたが、iOS13から利用可能な Core Haptics ではよりカスタマイズ可能な Haptic Feedback を実装することが可能になりました。
ということで、実際に Core Haptics を用いて Haptic Feedback を実装してみたいと思います!
実装の概要
以下の順番で実装していきます。
1, ライブラリ導入
2, 再生準備
3, 再生
4, パターン変更
注意点としては、バージョン11.0以降のXcodeがMacにインストールされている必要があることです。
(2019年6月現在では、Apple Developer Centerからbeta版をダウンロード出来ます。)
もう一点、今回実装する Haptic Feedback は、画像や動画では表現しづらいのを予めご了承ください。
(実機で動かして、確認してみてください。)
実際のソースコード
ライブラリ導入
利用するクラスに Core Haptics を import します。
import CoreHaptics
再生準備
利用するクラスで HapticEngine を定義します。
var hapticEngine: CHHapticEngine?
HapticEngine の利用準備をする関数を書き、呼び出します。
func setupHapticEngine() { do { hapticEngine = try CHHapticEngine() try hapticEngine?.start() } catch { print("There was an error creating the engine") } hapticEngine?.stoppedHandler = { reason in print("The engine stopped") } hapticEngine?.resetHandler = { [weak self] in print("The engine reset") do { try self?.hapticEngine?.start() } catch { print("Failed to restart the engine") } } }
(参考にしたページ)
Preparing Your App to Play Haptics | Apple Developer Documentation
再生
CHHapticEvent を作成する関数を作ります。
func createHapticEvents() -> [CHHapticEvent] { let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: 1) let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: 1) let event = CHHapticEvent(eventType: .hapticTransient, parameters: [intensity, sharpness], relativeTime: 0) return [event] }
(intensityは強度、sharpnessは鋭さ)
CHHapticPatternPlayer を再生する関数を書き、呼び出します。
func playHapticEngine() { do { let hapticPattern = try CHHapticPattern(events: createHapticEvents(), parameters: []) let hapticPlayer = try hapticEngine?.makePlayer(with: hapticPattern) try hapticPlayer?.start(atTime: 0) } catch { print("Failed to play") } }
(参考にしたページ)
Playing a Single-Tap Haptic Pattern | Apple Developer Documentation
パターン変更
上で作成した createHapticEvents を修正して、さまざまな Haptic をつくります。
(パターン1) 強くて鋭い Haptic
func createHapticEvents() -> [CHHapticEvent] { let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: 1) let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: 1) let event = CHHapticEvent(eventType: .hapticTransient, parameters: [intensity, sharpness], relativeTime: 0) return [event] }
(パターン2) 最初は強くて鋭いが、だんだんフェードアウトしていく1秒の Haptic
func createHapticEvents() -> [CHHapticEvent] { var events: [CHHapticEvent] = [] for i in stride(from: 0, to: 1, by: 0.1) { let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: Float(1 - i)) let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: Float(1 - i)) let event = CHHapticEvent(eventType: .hapticTransient, parameters: [intensity, sharpness], relativeTime: i) events.append(event) } return events }
(パターン3) SOS (...---...) みたいな Haptic
func createHapticEvents() -> [CHHapticEvent] { let short1 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 0) let short2 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 0.2) let short3 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 0.4) let long1 = CHHapticEvent(eventType: .hapticContinuous, parameters: [], relativeTime: 0.6, duration: 0.5) let long2 = CHHapticEvent(eventType: .hapticContinuous, parameters: [], relativeTime: 1.2, duration: 0.5) let long3 = CHHapticEvent(eventType: .hapticContinuous, parameters: [], relativeTime: 1.8, duration: 0.5) let short4 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 2.4) let short5 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 2.6) let short6 = CHHapticEvent(eventType: .hapticTransient, parameters: [], relativeTime: 2.8) return [short1, short2, short3, long1, long2, long3, short4, short5, short6] }
(参考にしたページ)
How to play custom vibrations using Core Haptics - free Swift 5.0 example code and tips
コードの全体像
おわりに
以上、iOS13で公開予定の「Core Haptics」を用いた Haptic Feedback の実装でした。
iOS13のリリース自体はまだ先でどうなるかわからないのですが、取り敢えずはこれを他のメンバーに提案してみたいと思います!
SHOWROOM は、最新技術を用いたり企画提案したいエンジニアにとってはとてもやりがいのある会社です。お気軽に問い合わせください!
recruit.showroom.co.jp