Tech Log/iOS

iOS ActivityKit 정리: Live Activity를 이론부터 프로젝트 적용까지 이해하기

별똥별 ⭐️ 2026. 3. 4. 17:24
728x90

이번 글에서는 iOS의 ActivityKit (Live Activity)을 학습하면서 정리한 내용을 하나의 흐름으로 정리해보려고 한다.

 

단순히 API 설명이 아니라 실제 프로젝트에 적용한 구조를 기준으로 정리했다.

 

글의 구조는 다음 5단계로 구성되어 있다.

 

  1. 이론 설명
  2. 내 프로젝트 기준 해당 작업
  3. 실제 프로젝트 작업 위치
  4. 알게 된 것
  5. 학습 핵심 요약

 

이 글 하나로 ActivityKit의 전체 구조를 잡는 것이 목표다.

 


 

1️⃣ ActivityKit 이론 설명

 

 

Live Activity란 무엇인가

 

Live Activity는 앱의 진행 상태를 잠금화면(Lock Screen) 또는 Dynamic Island에 실시간으로 보여주는 기능이다.

 

대표적인 예시는 다음과 같다.

 

  • 배달 상태 추적
  • 택시 이동 상황
  • 스포츠 경기 스코어
  • 운동 기록
  • 타이머 진행 상태

 

현재 진행 중인 이벤트 상태를 계속 업데이트하면서 보여주는 UI라고 볼 수 있다.

 

Apple에서는 Live Activity를 다음과 같이 설명한다.

 

Live Activities는 앱의 작업 진행 상황을 잠금화면이나 Dynamic Island에서 한눈에 확인할 수 있도록 하는 기능이다. 

 

일반 위젯과 차이도 중요하다.

구분특징

WidgetKit 일정 주기로 업데이트
Live Activity 상태 변화가 즉시 반영

Live Activity는 “현재 진행 상태”에 특화된 UI다.

 


 

2️⃣ ActivityKit 핵심 개념

 

Live Activity는 크게 3가지 개념만 이해하면 된다.

 

 

1. ActivityAttributes

 

Activity의 **고정 정보(static data)**를 정의한다.

 

예시

 

  • 주문 번호
  • 매장 이름
  • 사용자 이름

 

활동 동안 변하지 않는 데이터다.

 

예시 코드

struct DeliveryAttributes: ActivityAttributes {

    public struct ContentState: Codable, Hashable {
        var status: DeliveryStatus
        var eta: Date
    }

    var orderId: String
}

 


 

2. ContentState

 

Activity의 **변하는 상태(dynamic data)**를 정의한다.

 

예시

 

  • preparing
  • pickedUp
  • nearby
  • delivered

 

시간에 따라 계속 바뀌는 데이터다.

 

정리하면

ActivityAttributes → static data
ContentState → dynamic data

이 구조가 Live Activity의 핵심이다.

 


 

3. Lifecycle

 

Live Activity는 다음 흐름으로 동작한다.

start → update → end

 

Activity 시작

Activity.request(...)

 

상태 업데이트

activity.update(...)

 

Activity 종료

activity.end(...)

즉 구조는 매우 단순하다.

모델 정의
→ Activity 시작
→ 상태 업데이트
→ Activity 종료

 


 

3️⃣ 내 프로젝트 기준 ActivityKit 적용

 

이번 학습에서는 DeliveryTracker 시나리오로 ActivityKit을 구현했다.

 

프로젝트 구조는 크게 두 부분으로 나뉜다.

App
Widget Extension

 

App

 

Activity 상태를 제어하는 역할

 

예시

start
update
end

 

Widget Extension

 

Activity 상태를 받아 UI를 렌더링

 

예시

Lock Screen
Dynamic Island

이렇게 분리하는 이유는 간단하다.

 

👉 상태 제어와 UI 렌더링의 책임을 분리하기 위해서

 

실무에서도 동일한 구조를 사용한다.

 


 

4️⃣ 실제 프로젝트에서 수행한 작업

 

ActivityKit을 학습하면서 다음 작업을 진행했다.

 

 

Live Activity 모델 정의

DeliveryAttributes
DeliveryStatus

 

Debug 패널 구현

 

앱에서 다음을 테스트할 수 있게 구현

start
update
end

 

Activity Manager 구현

 

Activity lifecycle 호출을 Manager로 통합

DeliveryActivityManager

 

Lock Screen UI 구현

 

Live Activity 기본 화면 구성

 

 

Dynamic Island UI 구현

 

3가지 레이아웃 구현

Compact
Minimal
Expanded

 

Activity 모니터

 

현재 활성 Activity 추적

ActivityMonitor

 

로그 분리

AppActivityLogger
WidgetActivityLogger

 


 

5️⃣ 실제 프로젝트 코드 위치

 

프로젝트 구조는 다음과 같다.

https://github.com/YuSeongChoi/HIGLab/blob/main/practice/HIGPractice/HIGPractice/Learning/Phase-01-AppFrameworks/ActivityKit/ActivityKit.md

 

[스크린샷]

잠금 화면일 때
배달원 픽업
Dynmaic Island 표시

 

잠금화면과 다이나믹 아일랜드에 표시되는 위젯을 볼 수 있다

App (Activity 제어)

 

Debug Panel

DeliveryActivityDebugPanel.swift

Activity Manager

DeliveryActivityManager.swift

에러 처리

ActivityError.swift

Activity 상태 모니터

ActivityMonitor.swift

App Logger

AppActivityLogger.swift

 


 

Widget Extension (UI 렌더)

 

Live Activity Entry

DeliveryLiveActivity.swift

Lock Screen View

LockScreenView.swift

Dynamic Island Layout

DeliveryCompactLayout.swift
DeliveryExpandedLayout.swift

Widget Logger

WidgetActivityLogger.swift

 


 

Shared Model

 

앱과 위젯이 같은 모델을 사용하도록 공유

DeliveryAttributes.swift
DeliveryStatus.swift

이 부분이 상당히 중요하다.

 


 

6️⃣ 구현하면서 알게 된 것

 

ActivityKit을 직접 구현하면서 얻은 인사이트도 꽤 있었다.

 

 

1. 앱 / 위젯 분리는 필수

 

처음에는 하나의 구조에서 처리하려 했지만

 

상태 관리와 UI가 섞이면 구조가 복잡해진다.

 

분리 이후

 

  • 코드 가독성
  • 디버깅 속도
  • 유지보수

 

모두 개선되었다.

 


 

2. 모델 중복은 반드시 문제를 만든다

 

앱과 위젯에서

enum
struct

이 조금이라도 다르면 Activity 업데이트가 꼬일 수 있다.

 

그래서

Shared Model

구조가 필요하다.

 


 

3. 로컬 테스트와 실제 서비스는 다르다

 

학습 단계

앱 버튼으로 start / update / end 테스트

실제 서비스

서버 → push → live activity update

이 두 가지는 완전히 다른 시나리오다.

 


 

4. 로그는 앱 / 위젯 둘 다 필요하다

 

ActivityKit은 프로세스가 분리되어 동작한다.

 

그래서

 

  • 앱 로그
  • 위젯 로그

 

두 가지를 모두 확인해야 전체 흐름을 이해할 수 있다.

 


 

5. Live Activity UI는 단순해야 한다

 

Live Activity는 표시 공간이 매우 제한적이다.

 

특히 Dynamic Island는

 

  • compact
  • minimal
  • expanded

 

세 가지 레이아웃을 모두 고려해야 한다.

 

따라서 핵심 정보 중심 UI 설계가 중요하다.

 


 

7️⃣ 학습 핵심 요약

 

ActivityKit을 한 줄로 요약하면 다음과 같다.

 

ActivityKit은 상태 모델 + lifecycle + UI 렌더 분리 구조만 이해하면 된다.

 

핵심 포인트는 다음 5가지다.

 

 

1. ActivityAttributes / ContentState 구분

 

static(바뀌지 않는 정적) / dynamic(가변적) 데이터 분리

 

 

2. Activity lifecycle 통합

 

start / update / end는 Manager에서 관리

 

 

3. App / Widget 역할 분리

App → 상태 제어
Widget → UI 렌더

 

4. Shared 모델 사용

 

앱과 위젯 상태 계약 유지

 

 

5. 로컬 테스트 / 실제 서비스 구조 분리

로컬 테스트 → Debug Panel
실제 서비스 → Push 기반 업데이트

 


 

마무리

 

ActivityKit은 처음 보면 복잡해 보이지만 실제로는 다음 구조만 이해하면 된다.

ActivityAttributes
ContentState
Lifecycle
App / Widget 역할 분리

이 구조만 잡히면 Live Activity 구현 자체는 생각보다 단순하다.