0Pricing
Swift Academy · レッスン

App Extensionsの概要

共有、アクションなどのエクステンションについて理解します。

「App Extensionsの概要」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。

App Extensionとは

app extensionを使うと、コンテンツ共有、カスタムキーボード、Spotlightのインデックス作成など、アプリの機能を他のアプリやシステムの画面で提供できます。各Extensionは独立したターゲットであり、独自のライフサイクルとサンドボックスを持ち、システムが定義したエントリポイントから起動されます。

// Extensions run in their own process, launched
// by the host (Photos, Safari, Messages, the system),
// not by your main app.

ホスト、コンテナ、サンドボックス

関係するのは3つの要素です。host appがExtensionを呼び出し、container appがExtensionをアプリに含め、extension自体はサンドボックス内で実行されます。Extensionはアプリと自由に通信できません。両者はApp Groupを通じて通信し、メモリに直接アクセスすることはありません。

import Foundation
// Container app + Extension target share data via
// an App Group, e.g. group.com.example.app
let group = "group.com.example.app"
_ = group

Share Extension

Share Extensionはシステムの共有シートに表示され、ユーザーが任意のアプリからコンテンツ(テキスト、URL、画像)を自分のアプリに送れるようにします。ビューコントローラーをサブクラス化またはホストし、共有された項目をExtensionのコンテキストから読み取ります。

import Foundation
// Share extension reads incoming items:
// extensionContext?.inputItems
//   each NSExtensionItem has attachments (NSItemProvider)
let share = "appears in the share sheet"
_ = share

共有項目の読み取り

共有コンテンツはNSItemProviderの添付ファイルとして届きます。型識別子を確認し、値を非同期で読み込みます。これが、Share Extensionでユーザーが共有したURLや画像を取得する方法です。

import UniformTypeIdentifiers
func handle(_ provider: NSItemProvider) {
    if provider.hasItemConformingToTypeIdentifier(
        UTType.url.identifier) {
        provider.loadItem(
            forTypeIdentifier: UTType.url.identifier) {
            value, _ in
            print("shared url:", value ?? "none")
        }
    }
}

Action Extension

Action Extensionは、コンテンツをその場で変換または表示します。たとえば、選択したテキストを翻訳したり、PDFに注釈を付けたりして、ホストに結果を返せます。Share Extensionとは異なり、コンテンツを別の場所に送るのではなく、コンテンツに対して処理を行うためのものです。

import Foundation
// Action extension may return modified items:
// extensionContext?.completeRequest(
//     returningItems: outputItems)
let action = "acts on content, can return a result"
_ = action

Notification Service Extension

Notification Service Extensionは、mutable-content: 1を含む受信プッシュ通知を表示前に受け取り、短い時間内で内容を変更します。本文の復号、メディア添付ファイルのダウンロード、タイトルの書き換えなどが可能です。

import UserNotifications
// Override in UNNotificationServiceExtension:
// didReceive(_ request:, withContentHandler:)
//   mutate bestAttemptContent, then call the handler
let service = "modifies push before it shows"
_ = service

Notification Content Extension

Notification Content Extensionは、展開された通知に独自のUIを提供します。地図、メディアプレーヤー、インタラクティブなコントロールなどを表示でき、ユーザーがバナーを長押ししたときに表示されます。通知カテゴリに関連付けて使用します。

import UserNotifications
// UNNotificationContentExtension renders a custom view
// for a given UNNotificationCategory when expanded.
let content = "custom expanded notification UI"
_ = content

completeRequestのライフサイクル

Extensionの実行時間は短く制限されています。処理が終わったらextensionContext?.completeRequest(returningItems:completionHandler:)を呼び出して完了を通知し、ホストに自分を閉じさせます。途中で終了する場合はcancelRequest(withError:)を使用します。プロセスを開いたままにするとリソースを浪費し、強制終了される可能性があります。

import Foundation
func finish(context: NSExtensionContext?) {
    context?.completeRequest(
        returningItems: [], completionHandler: nil)
}

その他のExtension Point

iOSには、カスタムキーボード、Document Provider、Spotlightのインデックス作成、Safariのコンテンツブロッカー、Siri intent、写真編集、File Provider Extensionなど、多くのExtension Pointがあります。それぞれは、Info.plistのNSExtensionPointIdentifierで宣言された、システム定義のプロトコルに準拠します。

// Info.plist of an extension declares its point:
// NSExtension > NSExtensionPointIdentifier
//   e.g. com.apple.share-services
//        com.apple.usernotifications.service
let point = "each extension declares its point"
_ = point

メモリと時間の制限

Extensionはメインアプリより厳しい制限の下で実行されます。使用できるメモリが少なく、実行時間も短く制限されています。処理を最小限にし、大きなメモリ割り当てを避け、可能であれば共有ストレージを介して重い処理をメインアプリに任せてください。

import Foundation
// Tight memory + short runtime.
// Pattern: extension stages data in the App Group,
// the main app processes it fully on next launch.
let limits = "keep extensions lean and fast"
_ = limits

ターゲット間でコードを共有する

ロジックの重複を避けるには、アプリとExtensionの両方が依存するframeworkまたはSwift packageに、共有モデルとヘルパーを配置します。各ターゲットに必要なものだけを公開してください。Extensionは同じコードをコピーせずにリンクして使用できます。

import Foundation
// Shared Swift package 'AppCore' linked by:
//   - main app target
//   - share extension target
//   - widget extension target
let shared = "one source of truth for models"
_ = shared

確認問題

Extensionがコンテナアプリと通信する方法を思い出してください。

まとめ

App Extensionについて概観しました。

  • Extensionは、ホストによって起動される独立したサンドボックス化されたターゲットです。Share、Action、Notification Service、Notification Contentなどの種類があります。
  • NSItemProviderで受信コンテンツを読み取り、completeRequestで処理を完了します。
  • 各ExtensionはNSExtensionPointIdentifierを宣言し、厳しいメモリと時間の制限下で実行されます。
  • App Groupを通じてデータを共有し、共有パッケージでコードを再利用します。

よくある質問

「App Extensionsの概要」レッスンは無料ですか?

はい。「App Extensionsの概要」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。

「App Extensionsの概要」で何を学びますか?

共有、アクションなどのエクステンションについて理解します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Swift Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「App Extensionsの概要」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSwift Academyレッスンでコードを書いて実行できますか?

はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. WidgetKitウィジェットの構築
  2. タイムラインプロバイダーとスナップショット
  3. App Extensionsの概要
  4. App IntentsとShortcuts
← Swift Academyに戻る