「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 にレビューさせることから始めてみることをおすすめします。実装ミスの多くは初期セットアップの段階で潜んでいて、ストア申請直前に発覚するパターンが多いためです。