OpenAIExpo2026/03/12 13:30

The next generation of Expo APIs: MediaLibrary and Contacts

要点だけを先に読めるように短く再構成したセクションです。

元記事

Quick Digest

要約

要点だけを先に読めるように短く再構成したセクションです。

openaijamodel: gpt-5-mini-2025-08-07

Expoの次世代API:MediaLibrary と Contacts(SDK 55)

Key Points

  • 共有オブジェクト採用
  • クラスベースAPI
  • 部分更新と高速クエリ

Summary

SDK 55でexpo-contacts/nextexpo-media-library/nextが導入され、Shared Objects / Shared Refsを中心としたクラスベースAPIに移行しました。Asset/AlbumやContactオブジェクトはネイティブデータへのプロキシとして動作し、細粒度のゲッター、部分更新(patch())およびクエリビルダーにより、不要な全データ取得を避けて効率的に操作できます。

Key Points

  • パッケージ: expo-media-library/next, expo-contacts/next を利用。
  • MediaLibrary: Asset.create(uri)でアセット作成、Album.get()/Album.create()でアルバム操作。asset.getLocation() / asset.getShape() / asset.getInfo() のような細粒度ゲッターで必要なデータのみ取得。
  • 高度な検索はQueryビルダー(eq, gt, lte, within, orderBy, limit, offset, exe())で記述可能。ページングとソートを明示的に制御。
  • Contacts: Contact.create(), Contact.getAll(), Contact.presentPicker()で取得/作成。個別操作はaddEmail(), setImage()などインスタンスメソッドで行い、IDの手動管理が不要に。
  • 更新戦略: patch()は部分更新(未定義プロパティを無視)、update()は完全上書き。getDetails([...])と組み合わせるとフォームでの部分更新が簡潔かつ安全。
  • TypeScript: getDetails()で取得したフィールドに基づいて返り値の型が狭められ、未取得フィールドへのアクセスで警告が出るため型安全が向上。

Migration tips

  • 古いAPIでの大きなオブジェクト取得や手動ID渡しをやめ、インスタンスメソッドとゲッターに置き換える。
  • メディア検索やフィルタはQueryで集約し、クライアント側の不要な処理を減らす。
  • まずはexpo-contacts/next / expo-media-library/nextをインストールしてドキュメントを確認し、実装中の挙動差分をテストする。

詳細は新ドキュメントとGitHubでのフィードバックを参照してください。

Full Translation

翻訳

原文の流れを保ったまま読める翻訳セクションです。

openaijamodel: gpt-5-mini-2025-08-07

Expo APIの次世代:MediaLibrary と Contacts

Product • 2026年3月12日 • 読了時間: 約5分

Wiktor Smaga • Engineering

SDK 55ではコアライブラリの次世代が導入されます。Shared Objects & Shared Refs により、これらのライブラリでネイティブデータとやり取りする方法が根本的に変わります。Shared Objects と Shared Refs は、モジュール間の不要な結合を避けつつより深い統合を実現するため、Expoライブラリの将来だと考えています。Shared Objects と Shared Refs の詳細はこの記事を参照してください。

SDK 54では File System を新しいオブジェクト指向APIで更新しました。今回は Contacts と MediaLibrary のアップグレードです。更新されたライブラリは expo-contacts/next と expo-media-library/next として利用可能になっています。今後の SDK リリースでも他のライブラリへこれらの機能を順次導入していきます。

以下では contacts と media library パッケージで何が変わったかを見ていきます。

MediaLibrary@Next

コアコンセプト

新しい API はシンプルな考えに基づいています: Album と Asset はネイティブデータのプロキシとして動作するクラスになりました。これらはシステムギャラリー内のオブジェクトへの参照を保持し、メタデータを簡単に取得できます。新しいアセットを作成するには、ローカルURIを静的関数 Asset.create() に渡す必要があります。このコマンドはファイルをギャラリーに追加し、Shared Object を返します。

// Create an asset from a local URI
const asset = await Asset.create('file:///path/to/photo.png');

アセットを取得したら、管理はずっと直感的になります:

// Fetch an album and add the asset directly
const album = await Album.get('Holiday 2026');
await album.add(asset);

// Or create a new album and add the asset in one go
const album = await Album.create('Holiday 2026', [asset]);

プロパティへの直接アクセス

旧APIでのボトルネックは、getAssetInfoAsync() が返す巨大なオブジェクトのサイズでした。位置情報を確認するだけでも全プロパティを含む巨大なプレーンオブジェクトを取得しなければなりませんでした。MediaLibrary@Next は粒度の細かいゲッターを提供し、必要なものだけにアクセスできます。画像の寸法を確認するために全メタデータを取得する必要はもうありません。

await asset.getLocation(); // { longitude: 50, latitude: 20 }
await asset.getShape(); // { width: 100, height: 100 }
// すべて必要ですか?まだ可能です:
await asset.getInfo();

強力なクエリ

MediaLibrary@Next はメディアをフィルタリングする新しい方法を導入します。新しい Query クラスはビルダーパターンを採用しており、可読性の高い方法でより具体的なクエリを作成できます。サポートされる述語は以下の通りです: gt, gte, lte, lt, eq, within, album。また並び替え用の orderBy とページネーション用の limit / offset もサポートします。

const assets = await new Query()
  .eq(AssetField.MEDIA_TYPE, MediaType.IMAGE)
  .lte(AssetField.HEIGHT, 1080)
  .within(AssetField.WIDTH, [920, 960, 1080])
  .orderBy(AssetField.CREATION_TIME)
  .limit(20)
  .offset(10)
  .exe();

Contacts@Next

コアコンセプト

Contacts@Next の新しい API は以下の前提で設計されています: Contact オブジェクトはシステム連絡先への参照を保持し、基になるシステム連絡先の状態を取得・更新する多くの非同期関数を持ちます。旧APIとは異なり、毎回手動で ID を渡す必要はなく、特定の Contact インスタンス上で呼ばれる update 関数だけを頼れば、よくあるミスを避けられます。

開始するには、静的メソッドで連絡先を作成、取得、またはピッカーで選択できます:

// Create a new contact
const contact = await Contact.create({
  givenName: 'Andrew',
  familyName: 'Jones',
  phones: [
    { label: 'mobile', number: '+12123456789' },
  ],
});

// Fetch existing contact
const [contact] = await Contact.getAll({ limit: 1 });

// Or pick one using the system UI
const contact = await Contact.presentPicker();

粒度の細かい更新

単一のプロパティを更新するために巨大なJavaScriptオブジェクトを扱うのは誰も好きではありません。例えば旧APIで新しいメールアドレスを追加するには、オブジェクト全体を修正して送り返す必要がありました:

// THE OLD WAY
const updatedContact = {
  ...contact,
  emails: [
    ...(contact.emails || []),
    { address: 'contacts-next@expo.dev', label: 'work' }
  ],
};
await Contacts.updateContactAsync(updatedContact);

今では同じ操作を一行で行えます:

// THE NEW WAY
await contact.addEmail({ address: 'contacts-next@expo.dev', label: 'work' });

すべての連絡先プロパティに対して同様の操作が可能です。プロフィール画像を設定する例:

const result = await ImagePicker.launchImageLibraryAsync();
await contact.setImage(result.assets[0].uri);

高パフォーマンスなクエリ

特定のフィールドだけを取得したい場合、粒度の細かいゲッターが使えます:

const givenName = await contact.getGivenName();

複数のプロパティを取得するには getDetails を使います。興味のあるフィールドの配列を渡してください:

await contact.getDetails([ContactField.EMAILS, ContactField.FULL_NAME]);

連絡先の一覧を構築する場合は、より効率的な関数 getAllDetails() があります。内部では単一のシステムAPIコールを使用するため非常に高性能です。オプションのパラメータとして異なる種類のフィルタリングもサポートします。

// This is a static module function.
await Contact.getAllDetails([ContactField.EMAILS, ContactField.FULL_NAME]);

さらに、これらの関数が返すオブジェクトは引数で要求したフィールドに基づいて狭められた型になっています。TypeScript は取得していないフィールドにアクセスしようとすると警告を出します。

const details = await contact.getDetails([ContactField.GIVEN_NAME]);
console.log(details.givenName); // ✅ "John"
console.log(details.phones); // ❌ TypeScript will show a warning.

patch() + getDetails() の組み合わせ

新バージョンには HTTP の patch に似た patch() メソッドが含まれており、部分的な変更を適用します。undefined のプロパティはスキップされるため、変更したいフィールドだけを更新できます。getDetails() と組み合わせて設計されており、getDetails() が要求されたフィールドのみを取得し、patch() が定義されたフィールドのみを更新します。フォームで一つか二つのフィールドだけを変えるようなケースに最適です:

const details = await contact.getDetails([ContactField.EMAILS, ContactField.GIVEN_NAME]);
details.givenName = 'John';
await contact.patch(details); // システム上の givenName のみが更新される。

連絡先プロパティを完全に置き換えたい場合は、update メソッドを使うこともできます。patch と異なり、update は連絡先を丸ごと上書きします:

await contact.update({
  givenName: 'New Name',
  familyName: 'New Surname',
  // 他のフィールドはクリアされます
});

新しいドキュメントを確認してください

これらはライブラリの次の反復版であるため、皆さんのフィードバックがこれまで以上に重要です。GitHub issue、機能リクエスト、ツイートなど、どんなフィードバックでも歓迎し感謝します。API の動作例が載った新しいドキュメントもぜひご確認ください!