ClaudeExpo2026/03/12 13:30

The next generation of Expo APIs: MediaLibrary and Contacts

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

元記事

Quick Digest

要約

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

claudejamodel: claude-sonnet-4-20250514

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

Key Points

  • オブジェクト指向APIでMediaLibraryとContactsが大幅改善
  • 粒度の細かいプロパティアクセスでパフォーマンス向上
  • TypeScript型安全性とビルダーパターンで開発体験が向上

Summary

Expo SDK 55では、MediaLibraryとContactsライブラリが大幅にアップデートされ、Shared ObjectsとShared Refsを活用した新しいオブジェクト指向APIが導入されました。これらの新機能はexpo-contacts/nextexpo-media-library/nextとして利用可能です。

Key Points

MediaLibrary@Next

  • オブジェクト指向設計: AlbumAssetがクラスベースのプロキシオブジェクトとして動作
  • 粒度の細かいプロパティアクセス: getLocation()getShape()など必要な情報のみを取得可能
  • 強力なクエリシステム: Queryクラスでビルダーパターンを使用した柔軟な検索機能
  • 直感的なアセット管理: Asset.create()でファイルをギャラリーに追加、album.add(asset)で簡単操作

Contacts@Next

  • 参照ベースの設計: Contactオブジェクトがシステムコンタクトへのリファレンスを保持
  • 粒度の細かい更新: addEmail()setImage()など個別プロパティの更新が可能
  • 効率的なクエリ: getDetails()で必要なフィールドのみを取得、TypeScriptの型安全性も向上
  • パッチ機能: patch()メソッドで部分的な更新、getDetails()との組み合わせで最適化

Full Translation

翻訳

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

claudejamodel: claude-sonnet-4-20250514

次世代のExpo API: MediaLibraryとContacts

次世代の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では、新しいオブジェクト指向APIでFile Systemを更新しました。今度は、ContactsとMediaLibraryがアップグレードを受ける番です。

ライブラリの更新版はexpo-contacts/nextexpo-media-library/nextとして利用可能です。今後のSDKリリースでも、これらの機能を他のライブラリに継続的に導入していきます!

それでは、contactsとmedia libraryパッケージで何が変わったかを詳しく見ていきましょう。

MediaLibrary@Next

コアコンセプト

新しいAPIは、シンプルなアイデアに基づいて構築されています:AlbumAssetは、ネイティブデータのプロキシとして機能するクラスになりました。これらは、メタデータを簡単に取得するために、システムギャラリー内のオブジェクトへの参照を保持します。

新しいアセットを作成するには、静的なAsset.create()関数にローカルURIを渡す必要があります。このコマンドは、ファイルをギャラリーに追加し、shared objectを返します:

// ローカルURIからアセットを作成
const asset = await Asset.create('file:///path/to/photo.png');

アセットを取得したら、管理がより直感的になります:

// アルバムを取得してアセットを直接追加
const album = await Album.get('Holiday 2026');
await album.add(asset);

// または新しいアルバムを作成してアセットを一度に追加
const album = await Album.create('Holiday 2026', [asset]);

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

古いAPIの一般的なボトルネックは、getAssetInfoAsync()関数によって返されるオブジェクトのサイズでした。すべてのプロパティを含む巨大なプレーンオブジェクトを取得することなく、単純に位置情報をチェックすることができませんでした。

MediaLibrary@Nextは、必要なものだけに正確にアクセスできる粒度の細かいgetterを提供します。画像の寸法をチェックするためだけに、メタデータオブジェクト全体を取得する必要はもうありません。

await asset.getLocation(); // { longitude: 50, latitude: 20 }
await asset.getShape(); // { width: 100, height: 100 }

// すべてが必要?それでもできます:
await asset.getInfo();

強力なクエリ

MediaLibrary@Nextは、メディアをフィルタリングする新しい方法を導入します。新しいQueryクラスは、ビルダーパターンを活用し、非常に読みやすい方法でより具体的なクエリを作成できます。

以下の述語をサポートしています:gtgteltelteqwithinalbum - ソート用の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

コアコンセプト

新しいAPIは以下の前提に基づいて設計されました:

Contacts@NextのContactオブジェクトは、システム連絡先への参照を保持し、基盤となるシステム連絡先の状態を取得または更新するための多くの非同期関数を含んでいます。

古いAPIとは異なり、すべての関数呼び出しで手動でIDを渡す必要がなく、特定の連絡先のインスタンスで呼び出される更新関数のみに依存できるため、間違いやすいミスを多く回避できます。

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

// 新しい連絡先を作成
const contact = await Contact.create({
  givenName: 'Andrew',
  familyName: 'Jones',
  phones: [{
    label: 'mobile',
    number: '+12123456789',
  }],
});

// 既存の連絡先を取得
const [contact] = await Contact.getAll({ limit: 1 });

// またはシステムUIを使用して選択
const contact = await Contact.presentPicker();

粒度の細かい更新

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

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

今では、同じ操作をたった1行のコードで実行できます:

// 新しい方法
await contact.addEmail({ address: 'contacts-next@expo.dev', label: 'work' });

そして、これはすべての連絡先プロパティで実行できます!プロフィール写真を設定するのがいかに簡単になったかご覧ください:

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

パフォーマンスの良いクエリ

クエリについても同様です - 特定のフィールドを1つだけ取得したい場合は、粒度の細かいgetterを使用できます:

const givenName = await contact.getGivenName();

1つ以上のプロパティを取得するには、getDetailsを使用します。興味のあるフィールドの配列を渡すだけです:

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

連絡先のリストを構築している場合は、より効率的な関数getAllDetails()があります。内部では単一のシステムAPI呼び出しを使用するため、非常にパフォーマンスが良いです。オプションのパラメータとして、さまざまなタイプのフィルタリングもサポートしています。

// これは静的モジュール関数です。
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が警告を表示

.patch() + .getDetails() = ♥

ライブラリの新しいバージョンには、HTTPプロトコルのものと同様のpatch()メソッドが含まれており、部分的な変更を適用します。未定義のプロパティをスキップするため、実際に変更したいフィールドのみを更新します。

getDetails()とスムーズに連携するように設計されています:getDetails()は要求されたフィールドのみを取得し、patch()は定義されたもののみを更新します。これは、1つまたは2つのフィールドのみを変更するフォームに最適です:

const details = await contact.getDetails([ContactField.EMAILS, ContactField.GIVEN_NAME]);
details.givenName = 'John';
await contact.patch(details); // システム内のgivenNameのみを更新

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

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

新しいドキュメントをチェック

これらのライブラリの次のイテレーションであるため、皆様のご意見がこれまで以上に重要です。フィードバック、GitHubのissue、機能リクエスト、またはツイートなど、どのようなご意見でもオープンに受け入れ、非常に感謝しています。

また、APIが実際にどのように動作するかの例を見つけることができる新しいドキュメントもぜひご確認ください!