-
Macへのライブアクティビティの導入
Macアプリからライブアクティビティを配信・制御する方法を紹介します。ライブアクティビティがメニューバーやDynamic Islandにどのように表示されるかを解説します。データモデルの定義方法、SwiftUIを使用したコンパクト表示や拡大表示の作成方法、さらにApp Intentsを活用してインタラクティブなアップデートをトリガーする方法を学びます。
関連する章
- 0:00 - Introduction
- 0:54 - Live Activities on Mac
- 1:43 - Define the data model
- 2:51 - Build the views
- 4:40 - Start and update an activity
- 5:38 - Add actions
- 6:25 - End an activity
- 6:44 - Next steps
リソース
- Starting and updating Live Activities with ActivityKit push notifications
- Displaying live data with Live Activities
関連ビデオ
WWDC23
-
このビデオを検索
-
-
2:36 - Define the Live Activity data model
import ActivityKit struct CurtainActivityAttributes: ActivityAttributes { let scenesPerAct: [Int] let showTitle: String struct ContentState: Codable, Hashable { var isPlaying: Bool var curtainOpen: Bool var actIndex: Int var sceneIndexInAct: Int } } -
3:20 - Configure compact, minimal, and expanded views
import SwiftUI import WidgetKit struct CurtainActivityWidget: Widget { var body: some WidgetConfiguration { ActivityConfiguration( for: CurtainActivityAttributes.self ) { context in CurtainActivityMenuBarExpandedContent( state: context.state, showTitle: context.attributes.showTitle) } dynamicIsland: { context in DynamicIsland { DynamicIslandExpandedRegion(.leading) { CurtainLabel(state: context.state) } DynamicIslandExpandedRegion(.trailing) { ActLabel(state: context.state) } DynamicIslandExpandedRegion(.center) { SceneLabel(state: context.state) } DynamicIslandExpandedRegion(.bottom) { ExpandedBottom(state: context.state) } } compactLeading: { StatusGlyph(state: context.state) } compactTrailing: { CompactTrailing(state: context.state) } minimal: { StatusGlyph(state: context.state) } } } } -
5:23 - Update a running Live Activity
contentState.curtainOpen = false let content = ActivityContent( state: self.currentContentState, staleDate: nil ) await activity.update( content, alertConfiguration: alertConfiguration ) -
6:02 - Define an App Intent action
struct SetPlacesReadyIntent: AppIntent { // ... func perform() async throws -> some IntentResult { // ... var state = activity.content.state state.placesReady = self.ready let content = ActivityContent(state: state, staleDate: nil) await activity.update( content, alertConfiguration: .announcement(self.ready ? "Ready" : "Not Ready") ) return .result() } } -
6:16 - Trigger the intent from buttons
private struct PlacesReadyButtons: View { var body: some View { HStack { Button(intent: SetPlacesReadyIntent(ready: false)) { Text("Not Ready") } .tint(.red) Button(intent: SetPlacesReadyIntent(ready: true)) { Text("Ready") } .tint(.green) } } } -
6:32 - End a Live Activity
// End a Live Activity await activity.end(nil, dismissalPolicy: .immediate)
-