◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/Claude Code
⟐ Claude Code/2026-05-06中級

react-native-permissions か Expo か — Claude Code で迷わず実装する React Native 権限管理ガイド

react-native-permissionsとExpoパーミッションAPIの使い分け基準を解説。Claude Codeを活用してiOS・Android両対応の権限管理を最短で実装するパターンと、よくある実装ミスへの対処法を紹介します。

Claude Code265React Native3Exporeact-native-permissionsモバイルアプリ3iOS26Android7権限管理

「react-native-permissions を使うべきか、それとも別のライブラリがあるのか」——React Native でカメラや位置情報を扱おうとするとき、まず権限管理の選択で立ち止まる方は多いと思います。

私も初めて Expo の managed workflow から bare workflow へ移行したとき、expo-permissions がすでに非推奨になっていることに気づかず、古いドキュメントをしばらく参照し続けてしまいました。この選択を誤ると、iOS の Info.plist 設定漏れや Android の manifest エラーが後から連鎖するため、最初の方針を正しく固める点が肝心です。

Claude Code はこうした「ライブラリ選択の判断 + 実装」を一気通貫でサポートしてくれます。ここでは権限管理ライブラリの使い分け基準と、Claude Code を活用した実装パターンをまとめます。

ワークフローの構成で答えが変わる

まず押さえておきたいのは、「何を使うべきか」の答えがプロジェクトの構成によって変わるという点です。

Expo Managed Workflow の場合、個別の Expo パッケージ(expo-location・expo-camera・expo-media-library など)が現在の推奨です。かつての expo-permissions は廃止され、各機能パッケージにパーミッション処理が内包される形に変わりました。app.json の permissions フィールドと連動しているため、Info.plist や AndroidManifest.xml の手動編集が不要です。

Expo Bare Workflow または React Native CLI の場合、react-native-permissions が現在の事実上の標準です。iOS と Android を統一した API で扱えるため、プラットフォーム分岐を最小限に抑えながら実装できます。

Claude Code にプロジェクトの構成を伝えると、どちらを使うべきか自動的に判断した上で実装案を提示してくれます。

react-native-permissions の基本セットアップ

bare workflow のプロジェクトでカメラと位置情報の権限を管理する場合、Claude Code に次のように指示するとスムーズです。

react-native-permissions v4 を使って、カメラと位置情報(使用中のみ)の権限を
iOS・Android 両対応で実装してください。
iOS の Info.plist と Android の AndroidManifest.xml の設定も含めてください。
永続的に拒否された場合は設定画面へ誘導する処理も必要です。

Claude Code が生成する実装はおおよそ次のようになります。

import { Platform } from 'react-native';
import {
  PERMISSIONS,
  RESULTS,
  check,
  request,
  openSettings,
} from 'react-native-permissions';
 
// プラットフォームに応じたパーミッション定数
const CAMERA_PERMISSION =
  Platform.OS === 'ios'
    ? PERMISSIONS.IOS.CAMERA
    : PERMISSIONS.ANDROID.CAMERA;
 
const LOCATION_PERMISSION =
  Platform.OS === 'ios'
    ? PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
    : PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION;
 
/**
 * カメラ権限をリクエストする。
 * BLOCKED(永続拒否)の場合は設定画面へ誘導し、false を返す。
 */
export async function requestCameraPermission(): Promise<boolean> {
  // まず現在のステータスを確認
  const currentStatus = await check(CAMERA_PERMISSION);
 
  if (currentStatus === RESULTS.GRANTED) {
    return true;
  }
 
  if (currentStatus === RESULTS.BLOCKED) {
    // BLOCKED = ユーザーが「許可しない」を選択済みで、
    // システムダイアログはもう出ない。設定画面へ誘導する
    await openSettings();
    return false;
  }
 
  // DENIED または UNAVAILABLE 以外 → 初回リクエスト
  const result = await request(CAMERA_PERMISSION);
  return result === RESULTS.GRANTED;
}

このコードで重要なのは check() と request() を分けている点です。iOS では一度ユーザーが「許可しない」を選ぶと BLOCKED 状態になり、その後に request() を呼んでもシステムダイアログは表示されません。check() を省略して request() だけ呼ぶ実装は、初回は動いているように見えて「なぜかダイアログが出ない」という謎のバグの原因になります。

Expo Managed Workflow での対応パターン

Expo managed workflow の場合、同じ位置情報の権限を expo-location で実装すると次のようになります。

import * as Location from 'expo-location';
 
export async function requestLocationPermission(): Promise<boolean> {
  const { status } = await Location.requestForegroundPermissionsAsync();
 
  if (status !== 'granted') {
    // Expo ではステータスが 'denied' の場合に永続拒否を判別する
    console.warn('位置情報の権限が得られませんでした: status =', status);
    return false;
  }
 
  return true;
}

そして app.json 側の設定:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSLocationWhenInUseUsageDescription": "地図表示のために位置情報を使用します"
      }
    },
    "android": {
      "permissions": ["ACCESS_FINE_LOCATION"]
    }
  }
}

Claude Code に「app.json も更新して」と指示するだけで、コードと設定ファイルの両方を一括で整合性を保ちながら修正してくれます。設定の書き漏れによるストア審査リジェクトを防ぐ上で、この一括修正は特に助かります。

開発でよく遭遇する3つのミス

ミス 1: iOS シミュレータで UNAVAILABLE が返ってくる

カメラ・Bluetooth・モーションセンサーなど、物理ハードウェアに依存するパーミッションは、iOS シミュレータで UNAVAILABLE を返します。これをエラーと誤認識してデバッグに時間を取られるケースがあります。

Claude Code に「シミュレータで UNAVAILABLE になるパーミッションの一覧と対処方針を教えて」と尋ねると、パーミッション別の注意点をまとめてくれます。実機テストが必須なものと、モックで対応できるものを最初に整理しておくと、開発の流れがスムーズになります。

ミス 2: request() を画面遷移のたびに呼ぶ

権限リクエストを「画面を開くたびに呼ぶ」実装は、初回こそダイアログが出て正常に見えますが、2回目以降は何も起きません(iOS の仕様)。権限ステータスを React Context や useState でキャッシュし、アプリ起動時に一度だけ確認する設計が正しい方法です。Claude Code に「権限状態のキャッシュ戦略も含めたカスタムフックで実装して」と伝えると、Context ベースの設計を提案してくれます。

ミス 3: iOS の Privacy Manifest 未対応

2024年以降、Apple はプライバシーに関わる API を使うアプリに PrivacyInfo.xcprivacy ファイルの提出を義務づけています。react-native-permissions でカメラや位置情報を扱う場合、このファイルが正しく設定されていないとストア申請で拒否されます。Claude Code に「このプロジェクトで必要な PrivacyInfo.xcprivacy の内容を生成して」と指示すれば、使用している権限に対応した設定を出力してくれます。

Claude Code への指示のコツ

権限管理の実装を Claude Code に任せるときに効果的だったのは、制約条件を先にまとめて伝えることです。

このプロジェクトは Expo bare workflow です。
ターゲット: iOS 16.0 以上・Android API 33 以上。
ライブラリ: react-native-permissions v4。

以下の権限を管理するカスタムフック(usePermissions)を実装してください。
- カメラ
- マイク
- プッシュ通知

各権限について GRANTED / BLOCKED / DENIED を判別し、
BLOCKED の場合は設定画面へ誘導するダイアログを表示する処理も含めてください。

ライブラリのバージョンと最低サポート OS を伝えることで、廃止されたAPIを使ったコードが生成されるリスクを大幅に減らせます。私の経験では、この1文を加えるだけでコードの信頼性が格段に上がりました。

権限管理はユーザー体験とストア審査の両方に直結する実装です。地味に見えて手を抜けない部分ですが、Claude Code と組み合わせることで「動くだけでなく正しい」実装を最初から作れます。

Expo/React Native の全体的なワークフローについては、Claude Code × Expo/React Native — クロスプラットフォーム開発を加速する実践ガイドも参考にしてみてください。

まずは既存プロジェクトの権限コードを Claude Code にレビューさせることから始めてみることをおすすめします。実装ミスの多くは初期セットアップの段階で潜んでいて、ストア申請直前に発覚するパターンが多いためです。

シェア

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

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

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

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

関連記事

⟐ Claude Code2026-10-12
SPM に移したら、起動した瞬間にアプリが落ちるようになりました — dyld の一行を Claude Code と読み解いた記録
CocoaPods から Swift Package Manager へ移した直後、ビルドは通るのに起動した瞬間に落ちました。dyld の一行から原因を切り分け、直し方と確認コマンドまでをまとめます。
⟐ Claude Code2026-09-04
Claude Code に project.pbxproj だけは直接触らせていません
Xcode のプロジェクトファイルは、開けなくなる壊れ方より開けてしまう壊れ方のほうが高くつきました。直接編集をやめてスクリプト経由に寄せるまでに測ったことと、いま引いている線を書き残します。
⟐ Claude Code2026-08-12
課金ユーザーに広告が出る不具合を、判定の一元化で止めるまで
広告除去を購入した方に広告が出てしまう不具合の原因は、フラグの不足ではなく判定の分散でした。Claude Codeで広告SDKの呼び出し口を棚卸しし、単一の純粋な判定関数へ畳み込むまでの実装記録です。期限判定を端末時計に預けない工夫や、消し忘れを構造で防ぐ設計も紹介します。