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 を返します。
const asset = await Asset.create('file:
アセットを取得したら、管理はずっと直感的になります:
const album = await Album.get('Holiday 2026');
await album.add(asset);
const album = await Album.create('Holiday 2026', [asset]);
プロパティへの直接アクセス
旧APIでのボトルネックは、getAssetInfoAsync() が返す巨大なオブジェクトのサイズでした。位置情報を確認するだけでも全プロパティを含む巨大なプレーンオブジェクトを取得しなければなりませんでした。MediaLibrary@Next は粒度の細かいゲッターを提供し、必要なものだけにアクセスできます。画像の寸法を確認するために全メタデータを取得する必要はもうありません。
await asset.getLocation();
await asset.getShape();
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 関数だけを頼れば、よくあるミスを避けられます。
開始するには、静的メソッドで連絡先を作成、取得、またはピッカーで選択できます:
const contact = await Contact.create({
givenName: 'Andrew',
familyName: 'Jones',
phones: [
{ label: 'mobile', number: '+12123456789' },
],
});
const [contact] = await Contact.getAll({ limit: 1 });
const contact = await Contact.presentPicker();
粒度の細かい更新
単一のプロパティを更新するために巨大なJavaScriptオブジェクトを扱うのは誰も好きではありません。例えば旧APIで新しいメールアドレスを追加するには、オブジェクト全体を修正して送り返す必要がありました:
const updatedContact = {
...contact,
emails: [
...(contact.emails || []),
{ address: 'contacts-next@expo.dev', label: 'work' }
],
};
await Contacts.updateContactAsync(updatedContact);
今では同じ操作を一行で行えます:
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);
console.log(details.phones);
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)
連絡先プロパティを完全に置き換えたい場合は、update メソッドを使うこともできます。patch と異なり、update は連絡先を丸ごと上書きします:
await contact.update({
givenName: 'New Name',
familyName: 'New Surname',
});
新しいドキュメントを確認してください
これらはライブラリの次の反復版であるため、皆さんのフィードバックがこれまで以上に重要です。GitHub issue、機能リクエスト、ツイートなど、どんなフィードバックでも歓迎し感謝します。API の動作例が載った新しいドキュメントもぜひご確認ください!