タイマー系の小さなアプリを App Store に出していたとき、レビュー欄に「アプリを閉じると残り時間が分からなくなる」という声が続けて届きました。ホーム画面に戻っても、ロック画面でも、残り時間を見たい。その願いに応えられる場所が Dynamic Island です。
Rork Max は Swift のネイティブコードを生成してくれますが、Live Activity のように「アプリの外側に状態を出す」仕組みは、生成された雛形をそのまま動かすだけでは足りません。Extension のターゲット追加、表示状態の作り分け、更新の予算管理といった泥臭い部分は、結局こちらで手を入れることになります。ここでは、私自身が個人開発のアプリへ組み込んだときの順番でまとめます。
Dynamic Island は Live Activity の「もう一つの出力先」
最初に誤解を解いておきます。Dynamic Island は単独の API ではありません。ActivityKit の Live Activity を定義すると、その同じ状態が「ロック画面のバナー」と「Dynamic Island」の両方に流れていきます。つまり一つの状態モデルを書けば、表示先が二つ付いてくるという構造です。
Live Activity の中心は ActivityAttributes です。変化しない属性(タイトルなど)と、刻々と変わる ContentState(残り時間など)を分けて定義します。
import ActivityKitimport SwiftUIstruct TimerAttributes: ActivityAttributes { public struct ContentState: Codable, Hashable { var endDate: Date var isPaused: Bool } var taskName: String}
私の運用では、状態モデル(ActivityAttributes)と更新ロジックは自分で設計し、ロック画面ビューの初期レイアウトや色合わせのような部分を Rork Max に任せています。理由は単純で、状態設計を誤ると二つの表示先が同時に崩れ、後からの修正コストが高いからです。逆に見た目の調整は生成と手直しの往復が速く、AI に下書きさせる価値が大きい領域だと感じています。
Dynamic Island は「アプリを開いていない時間」に価値を届ける数少ない場所です。AdMob のような広告収益とは違い、ここは体験そのものの満足度に効きます。残り時間が島に出ているだけで、レビューの雰囲気が和らいだのを実際に見てきました。小さくても、最初の一つを通しておく価値は十分にあります。