Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - SwiftUI] 1. Live Activity (ActivityKit, Dynamic Island, 잠금 화면) - 개념 본문

iOS 응용 (SwiftUI)

[iOS - SwiftUI] 1. Live Activity (ActivityKit, Dynamic Island, 잠금 화면) - 개념

jake-kim 2022. 11. 20. 23:06

1. Live Activity (ActivityKit, Dynamic Island, 잠금 화면) - 개념

2. Live Activity (ActivityKit, Dynamic Island, 잠금 화면) - UI 구현 방법

3. Live Activity (ActivityKit, Dynamic Island, 잠금 화면) - UIKit에서 다이나믹 아일랜드 적용 방법

Live Activity 개념

  • 실시간 현황을 Dynamic Island나 잠금화면 또는 아이폰 화면에 보여주기 위해 나온 개념
  • Live Activity는 iPhone에서만 가능

https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities
Live Activity (잠금화면, Dynamic Island)
Dynamic Island

Live Activity 특징

  • Live Activity 업데이트는 오로지 ActivityKit으로 접근해야 가능
  • 최대 8시간 지속 가능 (8시간 경과 시 시스템에 의해 자동 종료)
  • ActivityKit과 remote push notification 업데이트 데이터는 4kb이하만 가능

WidgetKit 개념 (ActivityKit 이용시 필요 개념)

* 구체적인 WidgetKit 개념은 이전 포스팅 글 참고

  • 위젯 프로젝트
    • Widget Extension 템플릿 생성
    • Intent¡TimelineProvider, TimelieEntry로 위젯 업데이트 - 데이터, 업뎃 시점 제공
    • Widget 프로토콜 준수하는 구조체를 작성하여 body의 타입인 WidgetConfiguration 내부를 구현
  • WidgetConfiguration 종류
    • StaticConfiguration - 고정 UI 위젯
    • IntentConfiguration - 사용자 설정이 가능한 UI 위젯
    • ActivityConfiguration - Live Activity

-> 이번에 새로 나온 WidgetConfiguration을 이용하여 Live Activity 구현 가능

Dynamic Island 사용 플로우

  • info.plist에서 Live Active 활성화
  • File > New > Target > Widget Extension 클릭하여 위젯 확장 생성
  • DynamicIsland 클로저에서 UI 구현

Dynamic Island 사용 방법

  • info.plist에서 Live Activity 활성화
    • Supports Live Activities(==NSSupportsLiveActivities) 키를 추가하고, Value는 Yes로 설정

  • Xcode -> File -> Target 선택

  • Widget Extension 추가

  • Include Live Activity 선택하여 생성

  • 생성되는 주요 파일 3가지

1). DynamicIslandWidgetBundle.swift

  • 위젯의 UI를 표출하는 body가 있고, 이 body에는 아래에서 생성된 DynamicIslandWidget과 DynamicIslandWidgetLiveActivity이 나열되어 있는 일종의 ContainerView
@main
struct DynamicIslandWidgetBundle: WidgetBundle {
    var body: some Widget {
        DynamicIslandWidget()
        DynamicIslandWidgetLiveActivity()
    }
}

2). DynamicIslandWidget.swift

위젯 내용 - WidgetKit 개념은 이전 포스팅 글 참고

 

3). DynamicIslandWidgetLiveActivity.swift

  • Dynamic Island를 표현하는 뷰
  • ActivityKit을 import하고 있는 것을 확인
  • ActivityAttributes를 준수하는 struct한개와 Widget을 준수하는 struct가 존재
import ActivityKit
import WidgetKit
import SwiftUI

struct DynamicIslandWidgetAttributes: ActivityAttributes {
    public struct ContentState: Codable, Hashable {
        // Dynamic stateful properties about your activity go here!
        var value: Int
    }

    // Fixed non-changing properties about your activity go here!
    var name: String
}

struct DynamicIslandWidgetLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: DynamicIslandWidgetAttributes.self) { context in
            // Lock screen/banner UI goes here
            VStack {
                Text("Hello")
            }
            .activityBackgroundTint(Color.cyan)
            .activitySystemActionForegroundColor(Color.black)
            
        } dynamicIsland: { context in
            DynamicIsland {
                // Expanded UI goes here.  Compose the expanded UI through
                // various regions, like leading/trailing/center/bottom
                DynamicIslandExpandedRegion(.leading) {
                    Text("Leading")
                }
                DynamicIslandExpandedRegion(.trailing) {
                    Text("Trailing")
                }
                DynamicIslandExpandedRegion(.bottom) {
                    Text("Bottom")
                    // more content
                }
            } compactLeading: {
                Text("L")
            } compactTrailing: {
                Text("T")
            } minimal: {
                Text("Min")
            }
            .widgetURL(URL(string: "http://www.apple.com"))
            .keylineTint(Color.red)
        }
    }
}

 

  • 이 Acitivity 파일을 ContentView에서 사용해아하므로, Activity 파일의 TargetMemebership 체크

ContentView에서 위에서 만든 Activity 사용 방법

Start를 누르면 Live Activity 수행

  • 위에서 만든 DynamicIslandWidgetAttributes와 이 안에 있는 ContentState를 가지고 실행이 가능
  • ContentView에 버튼 하나 추가
import SwiftUI
import ActivityKit

struct ContentView: View {
  var body: some View {
    Button("Start") {
    	// TODO: request activity
    }
  }
}
  • 위에서 정의한 Attributes와 ContentState를 얻어서, reuqest()하여 Activity 기능 활성화
import SwiftUI
import ActivityKit

struct ContentView: View {
  var body: some View {
    Button("Start") {
      let dynamicIslandWidgetAttributes = DynamicIslandWidgetAttributes(name: "test")
      let contentState = DynamicIslandWidgetAttributes.ContentState(value: 7)
      
      do {
        let activity = try Activity<DynamicIslandWidgetAttributes>.request(
          attributes: dynamicIslandWidgetAttributes,
          contentState: contentState
        )
        print(activity)
      } catch {
        print(error)
      }
    }
  }
}

* 전체 코드: https://github.com/JK0369/ExActivityKit

 

* 참고

https://medium.com/better-programming/get-started-with-live-activities-and-the-dynamic-island-in-ios-16-f23d4f704128

https://developer.apple.com/design/human-interface-guidelines/components/system-experiences/live-activities

https://developer.apple.com/documentation/activitykit/update-and-end-your-live-activity-with-remote-push-notifications

https://developer.apple.com/documentation/activitykit/activityauthorizationerror

https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities

Comments