RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/開発ツール
開発ツール/2026-05-23中級

Rorkでexpo-hapticsが本番ビルドだけ無反応 — シミュレータ・実機・Low Power Modeの落とし穴

Rorkで生成したアプリで、ボタンタップ時のハプティクスがシミュレータでは効くのにTestFlight版だけ反応しない、片方のプラットフォームだけ鳴らない、突然鳴らなくなる――10本以上の壁紙系アプリで遭遇した原因と、Expo Hapticsの正しい呼び出しパターンを整理しました。

expo-hapticsiOS108Android43本番ビルドトラブルシューティング77

Rork で生成したアプリの「お気に入りに追加」ボタンを押したとき、Expo Go では指先に小さな振動が返ってくるのに、TestFlight に上げた瞬間まったく無反応になる――先週もまさにこのパターンで半日詰まりました。

私は2014年から壁紙系・癒し系のアプリを個人開発で運営していて、AdMob の eCPM 計測ついでにユーザー行動を眺めていると、ハプティクスが効いているアプリと効いていないアプリでは平均セッション時間が体感で1〜2割違います。たった数十ミリ秒の触覚フィードバックなのですが、無いと「タップした感」が消えてしまうので、本番で無反応のまま気付かずリリースしてしまうと、レビュースコアにじわじわ効いてくる地味に怖い不具合です。

expo-haptics 自体のコード量はごく少ないのですが、それゆえに「動かない理由が全部外側にある」のがやっかいなところ。原因を5つに分けて、上から順に潰していくと多くのケースで直ります。

まず切り分けるべき3つの観点

調査に入る前に、以下を確認します。これだけで原因の半分は絞れます。

  • 「実機の iPhone で物理的に振動しない」のか「振動はしているが弱くて気付かない」のか
  • iOS だけ無反応か、Android だけ無反応か、両方無反応か
  • Expo Go では動くのに EAS Build や TestFlight でだけ無反応か

シミュレータでは仕様上ハプティクスは絶対に発火しません。「シミュレータで動かない=バグ」ではないので、必ず実機で確認してください。私自身、新しい M シリーズの Mac に乗り換えた直後、シミュレータでデバッグばかりしていてここで時間を溶かしました。

原因1: iPhone 側のシステム設定でハプティクスが無効

最初に疑うべきは、ユーザー(または開発者自身)の iPhone 設定です。設定 → サウンドと触覚 → システムの触覚 がオフになっていると、expo-haptics の呼び出しは内部的にエラーを返さず黙ってスキップされます。

これは仕様で、Apple の HIG 上「触覚は OS 設定を尊重する」と書かれているため、アプリ側で強制発火させる正規 API はありません。本番でユーザーから「振動しない」報告が来たときは、まずこの設定を疑うようガイドする必要があります。

App Store のレビューで「振動しません」と書かれた星3を見て焦りましたが、原因はユーザーが触覚オフにしていただけ、というケースが体感で半数以上を占めます。アプリ内のヘルプに「触覚は iOS 設定の影響を受けます」と一文添えるだけでだいぶ減ります。

原因2: Low Power Mode で触覚エンジンが落ちる

iOS の Low Power Mode(低電力モード)に入っていると、Taptic Engine が省電力のために制限されます。Haptics.impactAsync を呼んでも音だけ鳴って振動しない、あるいはまったく無反応というケースが普通にあります。

これは Apple の公式仕様で、ドキュメントには明記が薄いものの、UIDevice.current.isLowPowerModeEnabled で取得できる状態と連動しています。React Native 側からは expo-battery で同等の判定ができます。

import * as Haptics from 'expo-haptics';
import * as Battery from 'expo-battery';
 
async function softTap() {
  const isLowPower = await Battery.isLowPowerModeEnabledAsync();
  if (isLowPower) {
    // 期待する出力: 触覚は省略、視覚フィードバックだけで代替する
    return;
  }
  await Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
}

UI 側で軽いカラーアニメーションを併走させておくと、低電力時でも「タップした感」が失われません。私が運営している壁紙アプリでは、画像保存成功時に必ず色変化+触覚のセットで返すようにしていて、低電力モードでも違和感ゼロにできています。

原因3: Android で expo-haptics を直接呼んでいる(VIBRATE 権限の罠)

Android では expo-haptics 内部で VIBRATE 権限を使います。Expo SDK 50 以降のデフォルト設定では権限が自動付与されますが、app.jsonandroid.permissions を手動で絞っていると VIBRATE が落ちることがあります。

app.json を以下のように明示します。

{
  "expo": {
    "android": {
      "permissions": ["VIBRATE"]
    }
  }
}

明示的に他の権限を列挙しているのに VIBRATE を書き忘れているケースが多いので、adb shell dumpsys package <package-name> | grep VIBRATE で実機上の権限を確認します。プレビュービルドで動いていても、本番ビルドで権限プロファイルが差し変わると無反応になるパターンがありますので注意が必要です。

原因4: イベントハンドラ内で await し損ねている

Rork が生成してくる定型コードでよく見るのが、onPress 内で await せずに Haptics.impactAsync を呼び出して、その直後に画面遷移してしまうパターンです。

// ❌ 触覚が間に合わずに画面遷移してしまう
<Pressable onPress={() => {
  Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
  router.push('/detail');
}}>

impactAsync は Promise を返すので、画面遷移が先に走ると遷移中の Activity がフォアグラウンドから外れて触覚自体がキャンセルされる挙動になります。

// ✅ 触覚を発火してから遷移する
<Pressable onPress={async () => {
  await Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
  router.push('/detail');
}}>

体感はわずか数十ミリ秒の差ですが、await の有無で「タップした感」が劇的に変わります。実装では「触覚→遷移」の順を守ることを徹底すると、本番で無反応に見える事象がほぼ消えます。

原因5: 連打されて触覚エンジンが詰まる

ハプティクスは内部キューを持っていて、短時間に連続発火させるとキューが詰まって以降の呼び出しが無視されます。スワイプで連続インタラクションを起こすカード型 UI などで、ユーザーが速くスワイプしたあと数秒間ハプティクスが止まる、という症状が出ます。

簡易的なスロットルで回避できます。

import * as Haptics from 'expo-haptics';
 
let lastHapticAt = 0;
const HAPTIC_MIN_INTERVAL = 80; // ミリ秒
 
export async function throttledLightImpact() {
  const now = Date.now();
  if (now - lastHapticAt < HAPTIC_MIN_INTERVAL) return;
  lastHapticAt = now;
  await Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
}

私の壁紙アプリでは、サムネをスワイプで切り替えるたびに発火するハプティクスがこれを入れる前は1秒間に8回くらい鳴ろうとして詰まっていました。80ms スロットルにすると、体感はむしろ「キレが良くなった」と感じられるくらいに改善しました。

本番リリース前に確認したいチェックリスト

ここまでの内容を本番チェックリストに落とすと次のようになります。

  • 実機(iOS/Android 両方)で物理的に振動するか
  • iOS のシステム触覚設定オン/オフ両方で意図通りの挙動か
  • Low Power Mode 時にフォールバック動作するか
  • 連打時に詰まらないか(80〜100ms スロットル推奨)
  • await で発火を待ってから遷移しているか

私の場合、TestFlight に上げた直後の Internal Testing で必ずこの5点を確認するワークフローにしてから、ハプティクス起因のレビュー指摘がほぼゼロになりました。地味な部分ですが、ここを丁寧にやるかどうかでアプリ全体の「触り心地」がはっきり変わります。

最後までお読みいただきありがとうございました。皆さんのアプリの触り心地が、少しでも気持ちよくなるきっかけになれば嬉しいです。

シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

開発ツール2026-05-10
Rork で expo-image-picker が起動しない — Info.plist と権限まわりで詰まった実例
Rork で生成したアプリの画像ピッカーボタンを押しても何も起こらない。Info.plist のキー不足、権限取得の順番、iOS 14 以降の Limited Photo Access、Android 13+ のメディア権限まで、実際に詰まった原因と解決策を整理しました。
開発ツール2026-05-04
Rork でマイク・音声録音が動かない——よくある原因と修正法を症状別に整理
Rork で生成したアプリでマイクや音声録音が機能しない場合の原因を症状別に解説。パーミッション設定・expo-audio の状態管理・iOS/Android の挙動差・シミュレーター制限まで、実際に詰まりやすいポイントを網羅しています。
開発ツール2026-05-02
Rork で StatusBar の色・スタイルが反映されない時の対処法
Rork で生成したアプリの StatusBar が iOS と Android で意図通りに表示されない問題を、実装パターン別に切り分けて解決する手順をまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →