メインコンテンツへスキップ
モバイル ガイド

Expo Image Picker 完全ガイド (2026年版)

React Nativeアプリでexpo image pickerを使いこなしましょう。インストール、権限設定、カメラ/ギャラリーへのアクセス、クロップ、base64、アップロードまでを網羅した完全ガイドです。

Expo Image Picker 完全ガイド (2026年版)

UIが完成し、プロフィール画面に「写真をアップロード」ボタンを配置したものの、ここからが意外と難しい、という段階にいるのではないでしょうか。実際の画像選択フローには、ネイティブの権限設定、OS制御のインターフェース、開発者の予想とは異なるレスポンス形式、そして実際にビルドして初めて直面するビルド時の詳細な仕様などが絡み合ってきます。

そこで役立つのがExpo Image Pickerです。これは、デバイスのライブラリから画像や動画を選択したり、カメラで写真を撮影したりするためのシステムUIを呼び出す、Expo公式のライブラリです。詳細は Expoパッケージリポジトリをご確認ください。実用面では、ネイティブのメディア入力への信頼できるブリッジを提供してくれますが、すべてのデバイスで全く同じ挙動をするカスタムメディア体験を提供するものではありません。

このガイドは、単なるデモ用ではなく、初めて実装する開発者のために書かれています。ManagedワークフローかBareワークフローかの選択、後で困らないための権限管理、安全な結果のパース、そしてユーザーがファイルを選択した後の実用的なアップロードパターンなど、プロダクション環境で重要となる意思決定に焦点を当てています。カスタムネイティブ環境で開発している場合は、 Expo EAS update options Capgo との違いを理解するのにも役立ちます。.

目次

Expo Image Pickerを始める

プロダクトマネージャーからプロフィール写真の機能要望がありました。しかし1週間後には、レシートのupload、事故報告用のカメラ撮影、さらにはユーザーが最初に権限を拒否した場合のリトライ機能まで求められるようになります。画像入力は、ネイティブの権限、OS標準のUI、一時ファイルの扱い、そしてバックエンドへのuploadフローに関わるため、急速に要件が拡大していきます。

expo-image-picker その役割を担うのがExpoのSDKモジュールです。これはプラットフォーム標準のピッカーやカメラUIを起動し、React Nativeのcodeで扱える形式で選択されたメディアを返します。JavaScriptのAPIは軽量です。主な課題は、ManagedおよびBareプロジェクトの両方において、ネイティブの設定、権限フロー、および結果のハンドリングを正しく実装することにあります。

主なトレードオフは明確です。カスタムピッカーを自作する代わりに、iOSとAndroid標準のメディアUIを利用します。これにより、ユーザーが使い慣れたシステム画面が表示され、権限のpromptもOSの期待通りに動作するため、通常はより良いユーザー体験が得られます。また、チームはJavaScriptでのギャラリー実装のメンテナンスから解放されます。

Reactインターフェースを備えたネイティブ統合機能として捉えてください。

この考え方は重要です。なぜなら、エラーの多くはピッカーを呼び出すボタン自体ではなく、主に以下の3つの要因から発生するからです。

  • ネイティブ設定: プラグイン設定の不足、権限文字列の誤り、または設定変更後のビルドの未更新
  • 実行時の挙動: ユーザーによるアクセス拒否、iOSでのライブラリへの限定的なアクセス許可、または選択なしでのフローの中断
  • 結果のパース: 現在の API は assets 配列を返すため、直接 result.uri 読み取ろうとする古い実装例では

Workflow choice also changes the setup path. In a managed Expo app, most of the native work lives in app config and requires a rebuild when that config changes. In a bare app, you still get the Expo module API, but you need to verify the underlying iOS and Android project settings more directly. If your team is using a custom client instead of Expo Go, this guide pairs well with Capgo’s Expo EASに代わる選択肢 Expo Goの枠を超えて、ネイティブモジュールのテストが必要なチーム向けです。

この違いは、本ガイドの残りの部分において重要です。なぜなら、正常系(happy path)だけでは不十分だからです。優れたピッカーの実装とは、両方のワークフローで動作し、ユーザーを困惑させることなくプラットフォーム固有の権限の挙動を処理し、ローカルプレビューで止まるのではなく、アップロード層に利用可能なファイルを渡せるものを指します。

インストールと必須設定

インストールはコマンド一つで完了します。しかし、ネイティブ設定を正しく行うことが、実機、カスタムDev Client、そして本番ビルドでピッカーが動作するかどうかを左右します。

expo-image-picker 写真、動画、カメラキャプチャ用のプラットフォームピッカーに対して、Reactから扱える API を提供します。JavaScriptからの呼び出しは簡単ですが、セットアップはそう簡単ではありません。写真やカメラへのアクセス権限は、React NativeではなくiOSやAndroidによって制御されているためです。

ノートPCの画面で code を入力しながら、Expo image pickerの実装に取り組む開発者。

まずはExpoのバージョン対応インストーラーから始めましょう:

npx expo install expo-image-picker

使用する expo install の代わりに npm install または yarn add。Expoはパッケージのバージョンを SDK と一致させるため、ネイティブの互換性に関するよくある問題を回避できます。Expoモジュールがリリースプロセスにどのように適合するかを比較している場合、これは Expoツール概要 は役立つリファレンスです。

Managed workflow のセットアップ

Managed workflow では、ビルド時に Expo がネイティブの変更を適用できるよう、app config でプラグインを宣言します。

〜を使った例 app.json:

{
  "expo": {
    "plugins": ["expo-image-picker"]
  }
}

これは最小限のセットアップです。実際には、特に iOS ではシステムプロンプトでアプリのアクセス理由を説明する必要があるため、権限テキストも追加するのが一般的です。文言はユーザーのアクションに合わせて具体的にしましょう。「メディアへのアクセスが必要です」よりも「プロフィール写真をアップロードします」の方が適切です。

運用上の細かい点が、多くの時間を無駄にします。設定の変更 plugins、権限文字列、その他のネイティブ設定には再ビルドが必要です。JavaScript のリロードではこれらの変更は適用されません。Expo Go では、クライアントに既に含まれている機能に制限されます。development build や production build では、新しいビルドを行って初めてネイティブプロジェクトに設定が反映されます。

Bare React Native のセットアップ詳細

Bare アプリでもパッケージ API は同じですが、ネイティブプロジェクトをより詳細に自身で確認する必要があります。まず確認すべきは iOS の usage descriptions です。ライブラリを開く、カメラを起動する、あるいは音声付きでビデオを録画するフローがある場合、アプリには対応する権限文字列が Info.plist 再ビルドする前に必要です。

Bare プロジェクト向けの実践的なチェックリストは次のとおりです:

  1. インストール expo-image-picker を使用して npx expo install expo-image-picker.
  2. Expo config pluginsを使用している場合は、プラグインの設定を追加してください。
  3. iOSのUsage Descriptionが、公開している機能と一致しているか確認してください。
  4. ネイティブ設定を変更した後は、必ずiOSとAndroidのアプリを再ビルドしてください。

権限のテキストが不足していると、UIの code は正常でボタンハンドラも動作するため、実行時のバグのように見えることがよくあります。実際には、より低レイヤーのスタックで失敗しています。私は通常、 Info.plistコンポーネントの code を触る前に、アプリの設定や、現在のビルドに最新のネイティブ変更が含まれているかを確認します。

以下の習慣をつけることで、セットアップの予測可能性が高まります:

  • 実際の動作に合わせて権限テキストを記述する: ユーザーがなぜプロンプトが表示されているのかを理解できるようにします。
  • カメラとライブラリを個別に設定する: 片方が失敗していても、もう片方は動作させることができます。
  • ネイティブ変更後は再ビルドする: hot reload や fast refresh では、ネイティブの権限設定は更新されません。
  • 実機でのテスト: シミュレーターの挙動では、権限やカメラに関する問題が隠れてしまうことがあります。

開発環境では動作するのに、TestFlight や Play Store のビルドで動かない場合は、まず設定の問題として疑ってください。ほとんどの場合、それが原因です。

カメラとメディアライブラリへのアクセス

ユーザーが「写真をアップロード」をタップし、カメラやライブラリが開くことを期待したとき、アプリに求められる役割は明確です。適切なシステムUIを開き、拒否やキャンセルが発生しても画面をクラッシュさせず、プレビューやアップロードに使えるローカルファイルの参照を返すことです。

iOS と Android の両方で managed および bare ビルドをテストしてみると、これが一筋縄ではいかないことがわかります。JavaScript の API は軽量なままですが、実行時の挙動は OS のプロンプト、デバイスのハードウェア、そして事前に設定したネイティブ権限に依存します。

カメラかメディアライブラリのどちらかを選択する、モバイルアプリの画像ピッカーのフローチャート。

最小限かつ安全なコンポーネント

コアとなるフローは、Expo の managed および bare ワークフローのどちらのプロジェクトでも共通です。関連する権限をリクエストし、ピッカーを起動し、ユーザーがキャンセルしたかどうかを確認してから、最初の資産を読み取ります。 result.assets.

ベースラインとなるコンポーネントは以下の通りです:

import { useState } from 'react';
import { View, Button, Image, Alert } from 'react-native';
import * as ImagePicker from 'expo-image-picker';

export default function PhotoInput() {
  const [imageUri, setImageUri] = useState<string | null>(null);

  const pickFromLibrary = async () => {
    const permission = await ImagePicker.requestMediaLibraryPermissionsAsync();

    if (!permission.granted) {
      Alert.alert('Permission required', 'Please allow photo library access.');
      return;
    }

    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ['images'],
      allowsEditing: true,
      quality: 1,
    });

    if (result.canceled) return;

    const asset = result.assets?.[0];
    if (!asset?.uri) return;

    setImageUri(asset.uri);
  };

  const takePhoto = async () => {
    const permission = await ImagePicker.requestCameraPermissionsAsync();

    if (!permission.granted) {
      Alert.alert('Permission required', 'Please allow camera access.');
      return;
    }

    const result = await ImagePicker.launchCameraAsync({
      allowsEditing: true,
      quality: 1,
    });

    if (result.canceled) return;

    const asset = result.assets?.[0];
    if (!asset?.uri) return;

    setImageUri(asset.uri);
  };

  return (
    <View>
      <Button title="Choose from library" onPress={pickFromLibrary} />
      <Button title="Take photo" onPress={takePhoto} />
      {imageUri ? (
        <Image
          source={{ uri: imageUri }}
          style={{ width: 200, height: 200 }}
        />
      ) : null}
    </View>
  );
}

ここで重要なポイントが3つあります。

  • ライブラリとカメラの権限は個別にリクエストしてください。それぞれ独立して失敗する可能性があります。
  • キャンセルはエラー状態ではなく、通常のユーザーアクションとして扱ってください。
  • から読み取ります assets[0]、なぜならピッカーはトップレベルの単一オブジェクトではなく、アセットの配列を返すためです uri.

ライブラリとカメラのフロー

機能を最短で実装したい場合は、まずライブラリのフローから始めましょう。テストが容易で、より多くのシミュレーター環境で動作し、カメラハードウェア特有のエッジケースを回避できます。結果のハンドリングが安定してから、カメラのサポートを追加してください。

カメラのフローは、開発中に失敗するパターンが多くなります。iOSシミュレーターのサポートは限定的です。Androidエミュレーターでは、実機と同じカメラ挙動が得られない場合があります。Bareプロジェクトでは、実際にはネイティブ設定やテスト環境の問題であるにもかかわらず、コンポーネントの code を調査することになりかねません。

クリーンなUIパターンとしては、API を呼び出す前に、ユーザーにソースを選択させることが推奨されます:

const showPickerOptions = () => {
  Alert.alert('Upload image', 'Choose a source', [
    { text: 'Camera', onPress: takePhoto },
    { text: 'Photo Library', onPress: pickFromLibrary },
    { text: 'Cancel', style: 'cancel' },
  ]);
};

このように分離することで、各関数の責務が明確になります。また、後からアナリティクスやフィーチャーフラグ、バックエンド固有のルールを追加しやすくなります。例えば、プロフィール画像にはライブラリからのアップロードを許可し、本人確認にはカメラでの新規撮影を必須とするチームもあります。

アプリ全体でExpo以外のファイルアクセスパターンをサポートしている場合や、他のネイティブスタックとの慣習を比較している場合、この Capacitor 写真ライブラリの参照 は有用なコンテキストとなります。

チームメンバーやQAにこのフローを説明する際は、短いデモがあると便利です:

システムUIの挙動について

expo-image-picker プラットフォームのピッカーまたはカメラUIが開きます。アプリ側ですべての画面を制御できるわけではありません。この違いは重要です。「自分のデバイスでは動いた」という言葉は、多くの場合「テストしたパスがOSに許可された」という意味に過ぎないからです。

iOSでは、ユーザーがフルアクセスではなく限定的なライブラリへのアクセスのみを許可する場合があります。Androidでは、OSのバージョンやベンダー独自のスキンによってピッカーの挙動が異なることがあります。Managed Workflowのプロジェクトでは、Expoがネイティブの紐付けの多くを代行してくれます。一方、Bare Workflowのプロジェクトでは、ビルドしたアプリに自身で行ったネイティブの権限変更が含まれているか確認する必要があります。JavaScriptの呼び出し箇所はどちらも同じでも、ランタイムの結果は異なる可能性があるためです。

私は通常、機能を「完了」とする前に以下のケースをテストします:

  • 最初の権限リクエスト
  • 権限の拒否
  • ユーザーによるキャンセル
  • ライブラリからの選択成功
  • 実機でのカメラ撮影成功
  • 返されたローカルURIの即時プレビュー

これらのケースは実際のプロダクション環境の挙動に直結します。また、ファイルをサーバーやモデレーション用のpipeline、あるいは以下のような公開エンドポイントに送信する必要がある場合、次のステップへスムーズに移行するための準備にもなります。 Instagramへのメディア投稿 API.

Pickerの結果とオプションの処理

Pickerの結果処理は、本番環境のロジックにおいて最も重要な部分です。システムUIは単なるファイルパスではなく、構造化されたオブジェクトを返します。ここでの小さなミスが、プレビューの表示失敗、アップロードの空振り、あるいはユーザーがキャンセルした際のクラッシュに直結します。

結果オブジェクトを正しく読み取る

現在のExpoアプリで重要となる結果の構造は result.assets[0].uriであり、トップレベルの result.uriではありません。ネイティブの設定は異なりますが、JavaScriptの API は共通であるため、この詳細はManagedおよびBareワークフローの両方のプロジェクトに影響します。

ガード節を優先するパターンを使用する:

const result = await ImagePicker.launchImageLibraryAsync({
  mediaTypes: ['images'],
  allowsEditing: true,
  quality: 1,
});

if (result.canceled) {
  return;
}

const asset = result.assets?.[0];
if (!asset) {
  return;
}

const { uri } = asset;
setImageUri(uri);

これにより、私が最も頻繁に遭遇する2つの失敗ケースに対処できます。Pickerがキャンセルされた場合は読み取るべきアセットが存在せず、また、常に存在すると仮定した code は result.assets[0] 実行時にエラーとなります。

URIを取得できれば、プレビューのレンダリングは簡単です:

<Image source={{ uri: imageUri }} style={{ width: 240, height: 240 }} />

後でアップロードする予定がある場合は、全体を保持しておいてください asset 単なるURIではなく、オブジェクトとして扱われます。実際には、 fileName, mimeType, width, heightや fileSize バリデーションやログ出力、よりクリーンなmultipartリクエストの構築に役立ちます。

後続の挙動に影響を与えるオプション

Pickerのいくつかのオプションは、選択画面だけでなく、ファイルサイズや編集時の挙動、バックエンドが受け入れ可能な形式にも影響を与えます。

オプション タイプ 変更される内容 一般的な用途
mediaTypes 配列 ユーザーが選択できる範囲を制限 API が画像のみを受け付ける場合は、選択を画像に限定してください
allowsEditing boolean 対応しているOSで、切り抜きや編集UIを表示します アバター、正方形のカバー画像、レシート撮影など
quality number 対応している画像出力を圧縮します モバイル回線でのuploadサイズを削減します
base64 boolean 結果にエンコードされた画像データを追加します インライン画像データを明示的に必要とする統合のみに使用してください

いくつか見落としがちなトレードオフがあります:

  • allowsEditing 画像の枠が固定の形状やサイズの場合に有効です。サーバー側で独自の切り抜きパイプラインを持っており、元のファイルが必要な場合はあまり有効ではありません。
  • quality upload時間、メモリ負荷、およびサーバーのストレージに影響します。 quality: 1 必ずしも最適な選択とは限りません。
  • mediaTypes バックエンドのルールに合わせる必要があります。サーバーが動画を拒否する場合は、pickerで動画を選択させないようにしましょう。
  • base64 メモリ上のペイロードサイズが増大します。受信側のサービスで必須でない限り、避けるべきです。

この最後の点は、メモリの少ないデバイスで重要になります。プレビューやmultipart uploadへの受け渡しには、通常ローカルファイルのURIの方が適しています。Base64にも用途はありますが、ファイル参照を渡す方法に比べるとコストが高くなります。

URI vs base64

ほとんどのアプリにおいて、ルールはシンプルです:

  • 使用する URI プレビュー用。
  • 使用する URI ファイルアップロード用。
  • 使用する base64 受信側システムがエンコードされたコンテンツを明示的に要求する場合のみ使用します。

このパターンにより、pickerの code を軽量に保ち、テストを容易にします。また、外部プラットフォームへ公開するサービスなど、多くのバックエンドのメディアフローの設計とも一致します。 Instagramへのメディア投稿 API.

頻繁にOTAアップデートを配信したり、画像中心のアセットをアプリ経由で提供したりする場合、ここでのファイルサイズの決定はパイプライン全体に影響します。こちらの アプリアップデート向けの画像最適化ガイド は、pickerの設定における有用な補足資料となります。

実用的なアプリ向けの、より安全な結果パターン

デモ用の code では、code のみを保存する形でも問題ありません。 imageUri しかし本番環境では、正規化されたオブジェクトを保存してください。そうすることで、プレビュー、バリデーション、upload、リトライといった後続のステップで、毎回生のpickerレスポンスを再解釈する必要がなくなります。

const result = await ImagePicker.launchImageLibraryAsync({
  mediaTypes: ['images'],
  allowsEditing: true,
  quality: 0.8,
});

if (result.canceled || !result.assets?.length) {
  return;
}

const asset = result.assets[0];

setSelectedImage({
  uri: asset.uri,
  fileName: asset.fileName ?? 'upload.jpg',
  mimeType: asset.mimeType ?? 'image/jpeg',
  width: asset.width,
  height: asset.height,
  fileSize: asset.fileSize ?? null,
});

これにより、アプリ内でのデータ構造が予測可能になります。また、他の部分でNative Buildの違いを扱っている間も、アプリの code が安定するため、managedプロジェクトとbareプロジェクトの整合性を保ちやすくなります。

最後に一つ確認です。念のため、不要な結果フィールドは有効にしないでください。必要なデータのみをリクエストし、ピッカーを単なるファイル処理ステップではなく、選択に特化したものとして保つことが重要です。

高度なパターンとプラットフォーム間の違い

ピッカー機能は、選択した最初の画像がリトライ、認証ヘッダー、ネイティブの権限の違い、そして実際のアップロードエンドポイントに対応しなければならない瞬間、一気に複雑になります。 expo-image-picker 選択処理はうまくこなします。残りの機能実装はアプリ側の責務です。

「画像のアップロード:ローカル vs サーバー保存の検討事項」と題された、サーバー保存のメリットとデメリットを示すインフォグラフィック。

実践的なアップロードパターン

ファイルアップロードを期待するAPIの場合、 FormData 依然としてこれが最も安全なデフォルトです。Rails、Node、Laravel、Django、Goなどの一般的なバックエンドで動作し、ピッカーを転送に関する関心事から切り離しておくことができます。

async function uploadImage(imageUri: string) {
  const formData = new FormData();

  formData.append('file', {
    uri: imageUri,
    name: 'upload.jpg',
    type: 'image/jpeg',
  } as any);

  const response = await fetch('https://your-api.example.com/uploads', {
    method: 'POST',
    body: formData,
    headers: {
      Accept: 'application/json',
    },
  });

  if (!response.ok) {
    throw new Error('Upload failed');
  }

  return response.json();
}

その code だけでパスが動作することの証明には十分ですが、本番環境のアプリでは通常、もう一層のレイヤーが必要です。可能な場合は選択されたアセットから抽出し、 name と type 認証はピッカー関数の外側で付与してください。また、アップロードの状態をピッカーの状態とは別に管理することで、リクエストが失敗してもユーザーがライブラリを再度開き直す必要がないようにします。

レビューで見かけるよくある失敗を防ぐためのチェック項目:

  • ローカルに存在するか uri リクエスト送信前に確認する
  • アップロード前にプレビューを表示し、ユーザーが誤ったファイルに早く気づけるようにする
  • リクエスト実行中の連打を防止する
  • ネットワークエラーを、ピッカーのキャンセルや権限エラーとは別に処理する
  • バックエンド側で、巨大なファイル、未対応のMIMEタイプ、認証エラーを拒否することを想定する

バックエンドがmultipartではなくbase64を要求する場合、それは通常サーバー側の制約であり、ピッカー側の要件ではありません。モバイルにおいては、multipartの方がメモリ消費が少なく、挙動の把握も容易です。

プラットフォーム間の違いが実際に影響する場面

ピッカーのUIはネイティブであるため、ネイティブの挙動を継承します。これはユーザーの見た目だけでなく、code が想定すべき挙動にも影響します。

iOSでは、編集フローや権限のプロンプトはAppleの規約に従います。写真へのアクセスが制限されている場合、権限が完全に付与されたデバイスのテストアカウントで見えていたものよりも、取得できるアセットの範囲が狭くなる可能性があります。Androidでは、OSのバージョンやメーカー独自のスキンによって、特にアルバム、ファイル名、カメラ撮影結果の返し方などの挙動が大きく異なります。Bare React Nativeアプリはネイティブ設定をより直接的に管理するため、これらの違いをより強く感じますが、managed Expoアプリであっても、ピッカーを完全に均一なものとしてではなく、プラットフォームごとの特性を持つものとして扱うcodeが必要です。

実用的なルールはシンプルです。デバイス間でUIやメタデータが同一であることを期待するのではなく、検証可能なフィールドに依存するようにしてください。

実際のアプリで重要となる例をいくつか挙げます:

  • 編集とクロップ: iOSとAndroidでUIやクロップの挙動が異なります
  • 返却されるメタデータ: fileName, mimeTypeや fileSize 欠落や不整合の可能性があるため、フォールバックを実装してください
  • 権限: iOSのフォトアクセスは選択したアイテムのみに制限されることがありますが、Androidの挙動はOSバージョンやシステムピッカーのサポート状況に依存します
  • カメラの出力: 撮影した画像は、ライブラリ内のアセットとは命名規則、向き、圧縮特性が異なる場合があります

チームがExpo以外でも開発を行っている場合、 DesignStack アプリ開発ガイド 単一のライブラリに留まらない、メディア処理の判断に役立つAndroidのコンテキストを提供します。

Managedとbareワークフローの違い

この段階になると、セットアップの選択が運用面に影響し始めます。

Managedワークフローでは、権限文字列やプラグイン設定は通常app configに記述され、ネイティブへの変更は新しいビルドを作成する際に適用されます。これによりJavaScriptの領域をクリーンに保てますが、設定の修正が次のNative Buildまで反映されないことも意味します。OTAアップデートでは、不足しているネイティブ権限を補完することはできません。

Bareワークフローでは、同じ機能でも構成要素が多くなります。iOSのUsage Description、Android Manifestの挙動、パッケージのインストール、そしてリビルドのタイミングを自身で検証する必要があります。メリットはコントロールができることですが、デメリットは、ピッカーの問題がJavaScriptの呼び出し側ではなく、ネイティブの設定に起因する可能性があることです。

ExpoからCapacitorへ移行するチームは、これらの抽象化レイヤーがいかに異なるかを過小評価しがちです.Capgoでは、以下について分かりやすく解説されています: Capacitorがプラットフォーム間の差異をどのように扱うかチームがどの程度のネイティブ設定を管理したいかを判断する際の、優れた比較基準となります。

私の推奨は、どちらのワークフローでも一貫しています。ピッカーのcodeは最小限に抑え、結果を一度正規化し、専用のAPIレイヤーを通じてuploadし、プラットフォーム固有の挙動は推測で済ませるのではなく、明示的に設定・テストすべきものとして扱うことです。

よくある問題のトラブルシューティング

Expo Image Pickerのバグの多くは、いくつかのカテゴリに分類されます。最も早い解決策は、config、権限、結果のハンドリング、レンダリングのどれに問題があるのか、失敗しているレイヤーを特定することです。

モバイル開発プロジェクトで expo-image-picker ライブラリを使用する際によくある問題のトラブルシューティング・チェックリスト。

よくある失敗を素早くチェック

ピッカーが開かない、または権限エラーが発生する場合は、まずネイティブの設定を確認してください。特にbareアプリでは、iOSのusage descriptions(使用目的の説明)の不足がよくある原因です。

ユーザーがピッカーを閉じた後にアプリがクラッシュする場合、結果のハンドリング処理を確認してください。多くの実装では、依然として直接的なURIが返されることを前提としており、 canceled 確認。

簡単な対応表を以下に示します:

  • 権限拒否(Permission denied)エラー: アプリの設定とネイティブの権限文字列を確認してから、再ビルドしてください。
  • undefined 画像URI: 読み取り元 result.assets?.[0]?.uriではなく、 result.uri.
  • キャンセル後、何も起こりません: その通りかもしれません。キャンセルは何もしない状態として処理してください。
  • 画像が表示されない場合: URIが正しくstateに保存され、以下に渡されているか確認してください: <Image source={{ uri }} />.
  • シミュレーターでカメラの挙動がおかしい場合: ライブラリのバグを疑う前に、まずは実機でテストしてください。

本番公開前の簡易チェックリスト

リリース直前の最終確認として活用してください:

  • Expoツールでのインストール: 使用する npx expo install expo-image-picker.
  • ネイティブ設定の構成: プラグインと必要な権限の説明文を追加します。
  • 意図したタイミングで権限をリクエストしてください: カメラとメディアライブラリのフローを分ける。
  • すべての結果をガードする: チェック result.canceled して安全に読み込む assets[0].
  • URIベースのアップロードを推奨: base64は特殊なケースのみに留める。
  • 実機でテストする: 特にカメラ撮影や権限のプロンプトを確認する。

チームが React Native プロジェクトに加えて Capacitor や Electron アプリを配信している場合、 Capgo JavaScript、CSS、設定、アセットのアップデートを、ストアの審査を待たずに配信する一つの手段となります。アップロードUI、バリデーションルール、文言、あるいはピッカー周りのアセット処理など、画像関連の修正がウェブレイヤーにある場合に非常に有効です。

Capacitor アプリ向けの Live Updates

Web レイヤーのバグが本番で発生したら、App Store の審査を何日も待たずに Capgo で修正を配信しましょう。ネイティブの変更は通常の審査フローに残したまま、ユーザーはバックグラウンドでアップデートを受け取れます。

最新のブログ記事

Capgoは、真にプロフェッショナルなモバイルアプリを作るために必要な最高のインサイトを提供します。