8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ZOZOAdvent Calendar 2022

Day 20

はじめてのライブアクティビティ

Last updated at Posted at 2022-12-19

この記事はZOZO Advent Calendar 2022Vol.1の20日目の記事です。

はじめに

本記事はiOS 16で追加されたライブアクティビティについての概要と実装についてのまとめです。

ライブアクティビティとは?

ライブアクティビティはiOS 16で追加されたアプリの最新データをDynamicIslandとロック画面に表示する機能です。
DynamicIslandはiPhone14 Pro、iPhone14 Pro Maxでのみ使用できます。(2022年12月時点)

iPhone14 Pro、iPhone14 Pro Max それ以外
ロック画面、
DynamicIsland
ロック画面

参照https://developer.apple.com/documentation/activitykit

ライブアクティビティを表示するには?

ライブアクティビティはActivityKitWidgetKitSwiftUIを使用して表示します。
まずはライブアクティビティの構成について紹介します。

ライブアクティビティの構成

ライブアクティビティを表示するのに必要になるのは3つです。

  • ライブアクティビティに表示するデータ
  • ロック画面に表示するView
  • DynamicIslandの表示要素

ライブアクティビティに表示するためのデータは静的なデータと動的なデータの2種類あります。
動的なデータを更新することで、ライブアクティビティの状態を更新することができます。
ロック画面、DynamicIslandのデータの表示にはActivityViewContextを使用します。

スクリーンショット 2022-12-19 3.02.22.png

ライブアクティビティとウィジェットの違い

ライブアクティビティはActivityKitだけではなくWidgetKitも使用しているため、構成はウイジェットと似ていますが、データを更新する方法が違います。
以下ウイジェットの構成です。ウイジェットはProviderというのを使用してデータの更新を行います。

スクリーンショット 2022-12-18 14.20.57.png

参照 https://developer.apple.com/documentation/WidgetKit

ライブアクティビティの実装

本記事では、ライブアクティビティを表示するところをピックアップして書きますので、詳細なライブアクティビティの作り方やライブアクティビティの更新、終了については触れません。

今回は以下のような静的なデータ1つと動的なデータ1つを表示するライブアクティビティを作成します。

スクリーンショット 2022-12-20 5.36.41.png

実装の流れは次の通りです。

  1. ライブアクティビティに表示するデータの作成
  2. ライブアクティビティ用のWidgetを作成
  3. ロック画面に表示するViewの作成
  4. DynamicIslandの表示要素の作成
  5. ライブアクティビティの起動

1. ライブアクティビティに表示するデータの作成

ライブアクティビティに表示するデータはActivityAttributesに準拠します。

struct SampleAttributes: ActivityAttributes {
    // 静的なーデータ
    var name: String

    // 動的なデータ
    public struct ContentState: Codable, Hashable {
        var time: Date
    }
}

2. ライブアクティビティ用のWidgetを作成

ライブアクティビティのウイジェットのConfigurationにはActivityConfigurationを使用します。

@main
struct SampleActivityWidget: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: SampleAttributes.self) { context in
            // ロック画面のView
        } dynamicIsland: { context in
            // DynamicIslandの要素
        }
    }
}

3. ロック画面に表示するViewの作成

次にロック画面用のViewを作成し、ライブアクティビティのConfigurationに設定します。

ロック画面に表示するViewは160ptの高さ以内にするのをおすすめします。高さ160ptを超える場合、ロック画面でライブアクティビティが切り詰められることがあるようです。

struct LockScreenLiveActivityView: View {
    let context: ActivityViewContext<SampleAttributes>
    
    var body: some View {
        VStack {
            Text("Hello \(context.attributes.name)")
            Text(context.state.time, style: .time)
        }
        .activityBackgroundTint(Color.cyan)
        .activitySystemActionForegroundColor(Color.black)
    }
}
@main
struct SampleActivityWidget: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: SampleAttributes.self) { context in
            LockScreenLiveActivityView(context: context)
        } dynamicIsland: { context in
            // DynamicIslandの要素
        }
    }
}

4. DynamicIslandの表示要素の作成

DynamicIslandでのライブアクティビティの表示は、ロック画面と異なり複数の表示形式があります。

表示方法 説明 画像
compact ライブアクティビティを1つだけ起動している場合に表示されます。
minimal 複数のライブアクティビティを起動している場合、minimalの表示になります。minimal表示は2パターンあり、システムがどのように表示するか決めます。
※minimalに表示する内容思いつきませんでした🙏

expand compactまたはminimalのをタップするとexpandが表示されます。

複数の表示方法がありますが、システムが状況にあった表示を行ってくれるので、DynamicIslandに表示するレイアウトを実装すれば良いです。
以下がDynamicIslandの実装です。

struct SampleLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: SampleAttributes.self) { context in
            LockScreenLiveActivityView(context: context)
        } dynamicIsland: { context in
            DynamicIsland {
                DynamicIslandExpandedRegion(.center) {
                    Text("Hello \(context.attributes.name)")
                }
                DynamicIslandExpandedRegion(.bottom) {
                    Text(context.state.time, style: .time)
                }
            } compactLeading: {
                // compactLeadingとcompactTrailingは分けて実装するが、まとまってcomactとしてDynamicIslandに表示される
                Text("Hello \(context.attributes.name)")
            } compactTrailing: {
                Text(context.state.time, style: .time)
            } minimal: {
                 Text("Min")
            }
        }
    }
}

これで、ライブアクティビティを表示する準備が出来ました。あとはライブアクティビティを起動するだけです。

5. ライブアクティビティの起動

ライブアクティビティの起動は request(attributes:content:pushType:)を呼びます。
ライブアクティビティはiPhoneのみでで使用できるかつ、ライブアクティビティを無効に設定することができるため、使用できるかのチェックをareActivitiesEnabledで行います。
また、ライブアクティビティは複数起動できますが、起動できる制限に達成した場合ライブアクティビティの起動に失敗する場合があるのでエラー処理をおこないます。

if ActivityAuthorizationInfo().areActivitiesEnabled {
    do {
        activity = try Activity<SampleAttributes>.request(attributes: .init(name: "edm"), content: .init(state: .init(time: .now), staleDate: Calendar.current.date(byAdding: .minute, value: 30, to: Date())!))
    } catch (let error) {
        // エラー処理
    }
}

以上でライブアクティビティを表示することができます。

おわりに

ライブアクティビティの構成や表示するまでの流れについてでした。
次は今回触れなかったライブアクティビティの更新、終了についてまとめたいと思います。

8
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?