代表的な面接トピック

安全で、デバイス間連携が可能で、取り消し可能なアクションのためのApp Intentsをどのように設計しますか?

プロダクト難しい
Offer.cc 編集チーム公開日 更新日

質問

あなたのコラボレーションアプリはすでにSiri、Spotlight、Shortcutsをサポートしています。ここで、ユーザーがデバイスをまたいで同じタスクを継続できるようにし、システムに関連するアクションを提案させたいと考えています。共有プロジェクトの削除など破壊的な操作には確認を必須とする必要があります。AppIntent、エンティティの識別性、認可、確認、冪等性、リカバリをどのように設計しますか?

1. シナリオ、ゴール、境界

コラボレーションアプリには、プロジェクト、コメント、タスクが含まれています。ユーザーはSiri、Spotlight、Shortcuts、またはApple Intelligenceを介して「タスクを完了」「プロジェクトを共有」「コメントを削除」などを呼び出すことができます。各エントリポイントは同じ認可と結果を維持する必要があり、タスクは別のデバイスで再開可能でなければなりません。

まず境界を設定します。App Intentsはアクションとエンティティのためのディスカバブルなインターフェースです。既存のサーバー認可、監査、トランザクションをバイパスしてはなりません。システムの提案によってリーチは広がりますが、呼び出し自体の信頼性が高まるわけではありません。すべてのIntentをパブリックな呼び出し面として扱います。

2. App Intentsのプロダクト価値

AppleのAppIntentプロトコルにより、アプリのアクションがSiri、Spotlight、Shortcuts、Apple Intelligenceから発見可能になります。2026年6月のApp Intentsアップデートでは、アプリスキーマ、SyncableEntityによる安定したデバイス間エンティティ識別性、OwnershipProvidingEntityによるセンシティブまたは破壊的アクションの所有権確認、他のアプリから提供されたコンテンツをパラメータとして受け取るIntentFileについても説明されています。

これらの機能はディスカバリとセマンティックな相互運用性を解決します。ビジネス上の認可、競合処理、取り消し(Undo)ポリシーを決定するものではありません。「ユーザーが何を望んでいるか」、「システムがそれを安全に実行できるか」、「ユーザーが失敗からどのように回復するか」を明確に分離してください。

3. アクションとエンティティのモデル化

各Intentについて、入力、可視性、前提条件、結果、副作用を定義します。表示名は変更される可能性がありますが、ビジネスIDは安定しており、検証可能で、現在のユーザーおよびテナントにバインドされている必要があります。リストの位置、タイトル、ローカルデータベースのキーをデバイス間の識別情報として使用しないでください。

swift
struct CompleteTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "Complete task"
    @Parameter(title: "Task")
    var task: TaskEntity

    func perform() async throws -> some IntentResult {
        try await TaskService.complete(taskID: task.id)
        return .result()
    }
}

エンティティの解決に失敗した場合、権限が変更された場合、またはバージョンの互換性がない場合は、理解しやすい選択肢やサインインへの誘導を返します。類似のプロジェクトを推測して実行することは絶対に避けてください。

4. 安定したデバイス間識別性の設計

タスクを複数のデバイスで継続できる場合、そのエンティティは安定した識別セマンティクスを公開する必要があり、サーバーは同じエンティティIDが各デバイスで同じリソースを参照することを保証しなければなりません。同期レイヤーは引き続き削除、アーカイブ、テナント移動、古くなったオフラインキャッシュを処理し、解決処理によって現在のユーザーがそのリソースにアクセスできることを再確認します。

SyncableEntityを同期データベースとして扱わないでください。これは識別性がデバイス間で安定して維持できることを表現するものであり、データ同期、競合解決、取り消しは依然としてバックエンドの責務です。古いShortcutが誤ったエンティティをターゲットにしないよう、マージや移行の際にもエイリアスマッピングと監査記録を保持してください。

5. センシティブなアクションと所有権の確認

削除、パブリック共有、アクセス権の譲渡を行う場合は、ユーザーがエンティティを所有しているか、必要な操作権限を持っていることを確認する必要があります。OwnershipProvidingEntityを使用して所有権を表現し、確認ダイアログでは対象オブジェクト、影響、可逆性について説明します。古い確認を再利用するのではなく、現在のリクエスト、ユーザー、リソースバージョンに確認をバインドしてください。

チーム所有またはパブリックなエンティティの場合、サーバーが所有権の判定を返す必要があり、ローカルキャッシュでは不十分です。「次回から確認しない」設定は狭い範囲に限定し、リスクの高いアクションについては確認と監査を維持します。

6. 認可、冪等性、副作用

システムがIntentを再試行したり、Shortcutが2回実行されたりする可能性があります。状態を変更するすべてのIntentは、冪等性キーとリソースバージョンを保持する必要があります。認可後、サーバーは条件付き更新を実行し、重複リクエストに対して同じビジネス結果を返します。読み取り専用アクションはより高速にできますが、それでも可視性の強制は必要です。

自然言語パラメータに権限をエンコードしないでください。セッション、テナント、エンティティの所有権、現在のバージョンから再認可を行い、エントリポイント(Siri、Spotlight、Shortcuts、アプリ内)、呼び出し元デバイス、結果を記録します。レスポンスでは、ログイン期限切れ、アクセス禁止、エンティティの変更、一時的なサービス障害を明確に区別します。

7. ディスカバリ、可観測性、リカバリ

すべての内部APIを公開するのではなく、ユーザー価値に基づいてアプリスキーマとディスカバブルなアクションを選択します。Intentごとに、解決成功率、認可拒否、確認の放棄、重複実行、デバイス間リカバリ、完了率を測定します。単なる呼び出し回数だけでなく、コンバージョンによってエントリポイントを比較します。

実行前に概要を表示し、実行後には取り消しパスを含む結果を表示します。ネットワークが中断した場合は、再試行可能なリクエスト状態を保持しますが、バックグラウンドで破壊的アクションを無期限に再実行してはなりません。エンティティが削除された場合やバージョン競合が発生した場合は、監査イベントを保持しながら、代替案と人間が対処するためのパスを返します。

8. ルーブリックとフォローアップ

必須の説明事項

  • App Intentsを、サーバーによる認可、監査、冪等性、バージョンチェックが依然として必要なパブリックなプロダクトインターフェースとして扱うこと。
  • 削除、移行、オフライン状態、競合などを含む実際のデータ同期と、安定したエンティティ識別性を区別すること。
  • センシティブなアクションに対する所有権の確認、範囲を限定した確認スキップ設定、取り消し(Undo)、障害リカバリを設計すること。

フォローアップ質問

  • ユーザーがスマートフォンで削除を確認した後、タブレット上のオフラインのShortcutがそれを再実行した場合、サーバーはどのようにして一貫した1つの結果を保証しますか?
  • 単一の所有者が存在しない共有チームプロジェクトの場合、誰が権限の譲渡を確認できますか?
  • ノイズが多く価値の低いアクションを追加するのではなく、あるIntentがシステムの提案に値するかどうかをどのように判断しますか?

採点ガイド

優れた回答は、ディスカバリ、識別性、認可、確認、冪等性、リカバリを1つのプロダクトチェーンとして結びつけます。システムのエントリポイントが意図を表現し、サーバーが最終決定を下し、ユーザーは影響を理解して失敗後も処理を継続できるようにします。

公開情報ソース

関連する質問