2026-06-27 OS 단 캐릭터 인터랙션 구현 가능성 심층 연구

부제: 민성이 아이디어의 "폰 안쪽 틈 세계"를 iOS 홈 화면, 위젯, 알림, Live Activity로 구현할 수 있는가

작성일: 2026-06-27

문서 성격: 구현 가능성 조사 보고서. 확정 구현안이 아니라, iOS에서 캐릭터가 앱 밖으로 확장되는 경험을 어디까지 만들 수 있는지 조사한 자료다.


0. 결론 요약

민성이 아이디어의 핵심인 "휴대폰 안쪽 틈 세계에 캐릭터가 살고 있다"는 감각은 완전히 구현 불가능한 아이디어가 아니다.

다만 iOS에서 다음은 불가능하거나 MVP 범위에서 제외하는 것이 맞다.

  • 홈 화면 위를 캐릭터가 자유롭게 돌아다니기
  • 다른 앱 아이콘 사이를 캐릭터가 오가기
  • 사용자의 실제 홈 화면 앱 배치를 읽어서 세계관으로 변환하기
  • 시스템 전체에 떠 있는 말풍선이나 펫 오버레이를 띄우기
  • 위젯 안에서 게임처럼 계속 움직이는 캐릭터를 상시 실행하기

반대로 다음은 가능하다.

  • 홈 화면 위젯에 캐릭터 상태와 대사를 보여주기
  • 위젯에서 버튼/토글로 간단한 상호작용하기
  • 잠금화면 위젯에 캐릭터의 현재 기분이나 오늘의 길 상태 보여주기
  • 산책 중 Live Activity로 잠금화면과 Dynamic Island에 캐릭터를 띄우기
  • 알림에 캐릭터 대사, 이미지, 액션 버튼 넣기
  • Control Center, 잠금화면, Action Button에 앱의 빠른 액션 넣기
  • App Intents와 Shortcuts/Siri/Spotlight를 통해 시스템 검색과 음성 명령에서 앱 액션 노출하기
  • HealthKit 배경 전달로 걸음수 변화를 감지하고 위젯/알림 상태를 갱신하기
  • 앱 아이콘을 사용자가 선택한 캐릭터나 성장 상태에 맞는 대체 아이콘으로 변경하기

따라서 제품 방향은 이렇게 잡는 것이 적절하다.

실제 iOS 홈 화면을 자유 조작하는 펫은 불가능하다.
하지만 위젯, 알림, Live Activity, Control, App Intents를 조합하면
사용자가 "이 캐릭터가 내 폰 바깥까지 따라온다"고 느끼게 만들 수 있다.

1. 연구 목적

이번 조사의 목적은 세 가지다.

  1. 듀오링고처럼 위젯과 알림 수준의 캐릭터 인터랙션을 구현할 수 있는지 확인한다.
  2. iOS 홈 화면, 잠금화면, Dynamic Island, Control Center, Action Button에서 앱이 어디까지 행동할 수 있는지 확인한다.
  3. 민성이 아이디어의 "휴대폰 화면 뒤쪽의 얇은 틈 세계"를 실제 제품 경험으로 번역할 수 있는 구현 전략을 제안한다.

조사는 GitHub 오픈소스 구현 사례를 먼저 보고, 그 다음 Apple 공식 문서로 가능/불가능 경계를 확인하는 순서로 진행했다.


2. GitHub 조사에서 확인한 구현 패턴

2.1 WidgetKit 예제

GitHub에는 WidgetKit 기반 홈 화면 위젯, 잠금화면 위젯, 인터랙티브 위젯, Live Activity 예제가 충분히 존재한다.

대표 예시:

WidgetExamples는 Basic widgets, Intent widgets, animated widget, Live Activity, iOS 17 관련 예시를 다룬다. SwiftUIWidgetDemo는 정적 위젯, 딥링크 위젯, 인터랙티브 위젯, 설정 가능한 위젯, Live Activity를 예제로 제공한다.

이 두 예제에서 확인할 수 있는 점은 다음이다.

  • 위젯은 SwiftUI와 WidgetKit으로 구현한다.
  • 앱 본체와 위젯 확장은 별도 타깃이다.
  • 앱과 위젯은 App Group/UserDefaults 등을 통해 상태를 공유한다.
  • 위젯은 앱을 열지 않고도 작은 정보를 보여줄 수 있다.
  • iOS 17 이후에는 App Intent 기반 버튼/토글 상호작용을 붙일 수 있다.

우리 앱에 적용하면 다음과 같다.

홈 화면 위젯
-> 캐릭터 표정, 오늘의 걸음, 길의 잔광, 짧은 대사 표시

인터랙티브 위젯 버튼
-> "인사하기", "오늘의 길 보기", "작은 빛 보내기"

2.2 TamagotchiPet 사례

가장 직접적으로 참고할 수 있는 예시는 Shakshi3104/TamagotchiPet이다.

이 프로젝트는 SwiftUI와 WidgetKit으로 만든 Tamagotchi 스타일 앱이며, 위젯에 펫을 표시한다.

이 사례가 중요한 이유는 "캐릭터/펫이 홈 화면 위젯에 머문다"는 제품 감각이 이미 기술적으로 가능한 패턴임을 보여주기 때문이다.

다만 우리 앱은 다마고치식 리셋이나 방치 벌칙보다, 걷기 데이터와 캐릭터의 사후 해석을 중심에 둔다. 따라서 구현 패턴만 참고하고 감정 설계는 다르게 가야 한다.

2.3 Live Activity와 Dynamic Island 예제

Live Activity 예제도 GitHub에 많다.

대표 예시:

이 예제들은 ActivityKit과 WidgetKit을 사용해 잠금화면과 Dynamic Island에 진행 중인 상태를 표시한다.

우리 앱에서는 Live Activity를 항상 켜두는 펫으로 쓰기보다, 사용자가 산책을 시작했을 때 켜지는 "길의 링크"로 쓰는 편이 맞다.

산책 시작
-> Live Activity 시작
-> 잠금화면과 Dynamic Island에 캐릭터가 "바깥의 빛을 받는 중"으로 표시
-> 산책 종료
-> Live Activity 종료
-> 앱 안에서 캐릭터가 하루를 해석

2.4 Control Widget / App Intent 예제

iOS 18 이후 Control Center, 잠금화면, Action Button에 앱의 빠른 액션을 노출할 수 있다.

GitHub에서 참고할 만한 구현 메모:

이 자료들은 ControlWidget, ControlWidgetButton, AppIntent, OpenIntent, OpenURLIntent를 사용해 Control Center나 잠금화면의 버튼에서 앱 기능을 실행하거나 앱의 특정 화면으로 이동하는 패턴을 보여준다.

우리 앱에 적용하면 다음과 같다.

  • Control Center 버튼: 길의 링크 시작
  • Action Button 액션: 산책 시작, 오늘의 해석 열기
  • 잠금화면 Control: 캐릭터에게 인사

Control은 캐릭터를 풍부하게 보여주는 공간은 아니지만, "OS 안쪽에 앱 액션이 들어왔다"는 감각을 만든다.

2.5 HealthKit 단계 수집 예제

걸음수는 HealthKit에서 가져올 수 있고, 배경 전달을 통해 앱이 업데이트를 받을 수 있다.

참고할 만한 GitHub 구현:

이 예제들은 HKQuantityTypeIdentifier.stepCount, HKStatisticsCollectionQuery, HKObserverQuery, enableBackgroundDelivery 같은 패턴을 사용한다.

우리 앱에서는 다음 흐름이 가능하다.

HealthKit stepCount 변경
-> 앱이 배경에서 업데이트 감지
-> 오늘 걸음 상태 계산
-> App Group 저장소에 CharacterState 저장
-> WidgetCenter.reloadTimelines 호출
-> 홈 화면 위젯의 캐릭터 상태 갱신

다만 HealthKit 배경 전달과 WidgetKit 갱신은 실시간 게임 루프가 아니다. OS가 배터리와 사용 패턴에 따라 스케줄링한다. 즉, "매초 반응하는 캐릭터"가 아니라 "하루 중 여러 번 자연스럽게 상태가 바뀌는 캐릭터"로 설계해야 한다.


3. Apple 공식 문서 기준 가능 범위

3.1 WidgetKit

Apple은 WidgetKit을 통해 앱의 콘텐츠를 앱 밖의 맥락에서 보여줄 수 있다고 설명한다. 위젯은 홈 화면, 잠금화면, macOS Notification Center, watch complication 등에서 glanceable content를 제공한다.

참고:

Apple 문서 기준 위젯의 역할은 다음에 가깝다.

앱의 가장 중요한 정보를 짧고 보기 좋게 보여주는 표면

우리 앱에서 위젯은 캐릭터의 "작은 창문"이 된다.

가능한 것:

  • 캐릭터 일러스트 또는 표정 표시
  • 오늘 걸음수와 세계관 언어 표시
  • 시간대에 따른 대사 변경
  • 누적 상태에 따른 배경 변화
  • Button/Toggle 기반 간단한 상호작용
  • 위젯 탭 시 앱의 특정 화면으로 이동

어려운 것:

  • 캐릭터가 실시간으로 계속 걷거나 움직이는 애니메이션
  • 홈 화면 전체를 캔버스처럼 쓰기
  • 다른 앱 아이콘과 직접 상호작용하기
  • 위젯 안에서 무거운 LLM 추론을 직접 실행하기

Apple은 Adding interactivity to widgets and Live Activities에서 위젯과 Live Activity에 버튼과 토글을 넣어 앱을 열지 않고 특정 기능을 제공할 수 있다고 설명한다.

따라서 우리 앱의 홈 화면 위젯은 다음 정도가 현실적이다.

위젯 크기 역할 예시
Small 캐릭터 표정과 짧은 상태 "오늘은 길의 소리가 조용해"
Medium 캐릭터 + 오늘의 잔광 + 버튼 "인사하기", "오늘 길 보기"
Large 둥지/틈 세계 미니 화면 캐릭터, 배경, 하루 요약, 다음 해금 힌트
Lock Screen 최소 정보 캐릭터 아이콘, 잔광 수치, 짧은 감정

3.2 Live Activities와 Dynamic Island

Apple의 Displaying live data with Live Activities는 Live Activity가 현재 데이터를 잠금화면, Dynamic Island, CarPlay, Mac, Apple Watch에 표시할 수 있다고 설명한다.

Apple의 Meet ActivityKit 설명에 따르면 Live Activity는 진행 중인 작업이나 이벤트의 상태를 추적하는 glanceable 경험이며, 명확한 시작과 끝이 있는 활동에 적합하다.

따라서 Live Activity는 "항상 살아 있는 펫"보다 "진행 중인 산책 링크"에 적합하다.

좋은 사용 예:

  • 산책 시작
  • 집중 걷기 세션
  • 퇴근길 기록
  • 특정 이벤트성 모험

나쁜 사용 예:

  • 하루 종일 켜진 캐릭터
  • 의미 없이 계속 유지되는 Live Activity
  • 앱 접속 유도 광고

우리 앱에서 Live Activity는 이렇게 쓰는 것이 좋다.

사용자가 산책을 시작한다.
캐릭터와 "길의 링크"가 열린다.
잠금화면에는 캐릭터가 바깥의 잔광을 받는 모습이 보인다.
Dynamic Island에는 작은 아이콘과 현재 잔광 상태가 표시된다.
산책이 끝나면 링크가 닫히고, 앱 안에서 캐릭터가 하루를 해석한다.

Live Activity의 동적 상태는 가볍게 유지해야 한다. Apple 문서의 Activity.update 설명은 state 크기가 4KB를 넘을 수 없다고 명시한다. 참고: Activity.update(_:alertConfiguration:timestamp:)

따라서 Live Activity에는 긴 대화나 LLM 응답을 넣지 말고, 짧은 상태만 넣는다.

예시:

{
  "phase": "walking",
  "stepsDelta": 1240,
  "glowLevel": 2,
  "characterMood": "curious",
  "shortLine": "바깥의 소리가 들려"
}

3.3 App Intents, Shortcuts, Siri, Spotlight

Apple의 App Intents는 앱의 콘텐츠와 액션을 Apple Intelligence, Siri, Spotlight, Shortcuts, widgets 같은 시스템 경험에 노출하는 프레임워크다.

Apple의 App Shortcuts는 앱 intent와 제목, 이미지, 음성 phrase를 결합해 사용자가 Shortcut으로 실행할 수 있게 한다.

우리 앱에서 App Intents는 캐릭터를 OS 안쪽으로 확장하는 핵심 레이어다.

가능한 액션 예시:

  • 오늘의 길 해석하기
  • 캐릭터에게 인사하기
  • 길의 링크 시작하기
  • 산책 종료하고 기록 보기
  • 오늘의 잔광 확인하기
  • 캐릭터 상태 보기

이 액션들은 다음 위치에 노출될 수 있다.

  • Shortcuts 앱
  • Siri phrase
  • Spotlight 검색
  • Widget 버튼
  • Control Center
  • Action Button

단, App Intent에서 무거운 LLM 추론을 직접 처리하는 것은 조심해야 한다. 짧은 상태 업데이트나 앱 열기, 사전 계산된 메시지 표시 정도가 안전하다. 긴 대화 생성은 앱 본체로 넘기는 것이 좋다.

3.4 Control Center, 잠금화면, Action Button

Apple의 Creating controls to perform actions across the system는 앱 액션을 Control Center, Lock Screen, Action Button에서 실행할 수 있게 한다고 설명한다.

Apple의 ControlWidget은 Control Center, Lock Screen, Action Button 같은 시스템 공간에 표시되는 control widget 구성을 제공한다.

우리 앱에서 Control은 캐릭터를 크게 보여주는 공간은 아니지만, 빠른 행동 진입점으로 좋다.

추천 Control:

Control 기능 세계관 표현
길의 링크 시작 산책 Live Activity 시작 바깥의 빛을 열기
오늘의 해석 앱의 하루 해석 화면 열기 오늘 가져온 길 보기
인사하기 캐릭터 상태를 짧게 갱신 틈 안쪽에 손 흔들기
조용 모드 알림 빈도 줄이기 오늘은 조용히 지켜보기

3.5 User Notifications

Apple의 User Notifications는 앱이 알림 종류와 사용자 액션을 정의할 수 있다고 설명한다. Declaring your actionable notification types에서는 카테고리와 액션 객체를 통해 사용자가 알림에 어떻게 응답할 수 있는지 정한다고 설명한다.

Apple HIG의 Notifications는 알림의 상세 뷰가 최대 네 개의 버튼을 포함할 수 있다고 설명한다.

우리 앱에서 알림은 듀오링고식 소통의 중요한 축이 될 수 있다.

가능한 알림:

  • 아침: "오늘 바깥은 어떤 길일까?"
  • 점심: "조금 걸었다면, 틈 안쪽에 빛이 닿았을 거야."
  • 저녁: "오늘 네가 지나온 길을 들려줄래?"
  • 산책 후: "방금 들어온 빛이 아직 따뜻해."
  • 며칠 조용한 날: "요 며칠은 길이 조용했어. 쉬어가는 중이었나 봐."

액션 버튼:

  • 오늘의 길 보기
  • 나중에
  • 조용히 하기
  • 인사하기

중요한 점은 듀오링고처럼 강한 압박을 그대로 따라 하면 안 된다는 것이다. 우리 앱은 놓치면 혼남보다 돌아오면 반겨줌이 맞다.

3.6 HealthKit 배경 전달

Apple의 HealthKit enableBackgroundDelivery는 HealthKit 저장소 변화를 모니터링하고 업데이트를 받을 수 있게 한다.

Apple의 Reading data from HealthKit는 observer query가 background delivery를 등록할 수 있으며, HealthKit이 업데이트 발생 시 앱을 깨울 수 있다고 설명한다.

이를 통해 걸음수 기반 캐릭터 상태 갱신이 가능하다.

구현 흐름:

1. 사용자에게 HealthKit stepCount 읽기 권한 요청
2. HKObserverQuery 등록
3. enableBackgroundDelivery 설정
4. 업데이트 발생 시 HKStatisticsQuery / HKStatisticsCollectionQuery로 오늘 걸음 재계산
5. 캐릭터 상태 요약을 App Group 저장소에 저장
6. WidgetCenter 또는 ControlCenter reload 요청
7. 필요 시 알림 예약 또는 Live Activity 업데이트

주의점:

  • HealthKit 업데이트는 초 단위 실시간 반응이 아니다.
  • 배경 실행은 OS 정책의 영향을 받는다.
  • 사용자가 권한을 거부하면 대체 경험이 필요하다.
  • 걸음수는 개인 건강 데이터이므로, 설명 문구와 개인정보 처리 방침이 명확해야 한다.

3.7 대체 앱 아이콘

Apple의 Configuring your app to use alternate app icons는 앱이 여러 아이콘을 제공하고, 사용자가 앱 안에서 선택하면 setAlternateIconName(_:completionHandler:)를 호출해 시스템에 표시되는 앱 아이콘을 바꿀 수 있다고 설명한다.

우리 앱에서는 이 기능을 "캐릭터가 홈 화면에 남긴 흔적"처럼 쓸 수 있다.

예시:

  • 기본 아이콘: 닫힌 틈
  • 마법사 선택 후: 지도 조각이 보이는 틈
  • 기사 선택 후: 금 간 검 문양
  • 정령 선택 후: 작은 둥지와 빛
  • 관계 성장 후: 더 밝아진 틈

단, 앱 아이콘은 사용자가 명시적으로 선택하거나 승인하는 경험으로 두는 편이 안전하다. 앱이 몰래 자주 바꾸는 연출은 불쾌하게 느껴질 수 있다.


4. 홈 화면에서 어디까지 자유로운가

가능한 것

영역 가능 수준 캐릭터 경험으로 번역
앱 아이콘 대체 아이콘 제공 가능 선택한 캐릭터의 흔적이 홈 화면에 남음
앱 배지 숫자 표시 가능 새 대화/새 해석/새 기억 수
홈 화면 위젯 캐릭터 상태 표시 가능 폰 안쪽 틈을 들여다보는 창
인터랙티브 위젯 버튼/토글 가능 인사하기, 오늘 길 보기
잠금화면 위젯 작은 상태 표시 가능 캐릭터의 짧은 기분/잔광 상태
Live Activity 진행 중인 활동 표시 가능 산책 중 길의 링크
Dynamic Island Live Activity 일부 표시 가능 걷는 동안 작은 캐릭터 상태
Control Center 빠른 액션 가능 길의 링크 시작/종료
Action Button 앱 액션 연결 가능 산책 시작, 캐릭터 부르기
Shortcuts/Siri 앱 액션 실행 가능 "오늘 길 해석해줘"
알림 대사, 이미지, 버튼 가능 캐릭터가 말을 건네는 느낌

불가능하거나 위험한 것

아이디어 판단 이유
홈 화면 위를 캐릭터가 자유롭게 돌아다님 불가능에 가까움 iOS는 앱이 홈 화면 위에 임의 오버레이를 띄우는 구조를 제공하지 않음
다른 앱 아이콘을 캐릭터의 집으로 직접 사용 불가능에 가까움 앱은 사용자의 실제 홈 화면 배치나 다른 앱 아이콘을 자유롭게 읽고 조작할 수 없음
위젯 안에서 상시 게임 루프 실행 부적합 위젯 확장은 앱이 아니며, 짧고 제한된 작업을 수행하는 구조
사용자가 앱을 안 열어도 LLM이 계속 대화 생성 부적합 배터리, 메모리, 배경 실행 제한 문제
알림을 너무 자주 보내 캐릭터 생존감을 만듦 위험 알림 피로와 권한 해제 가능성
홈 화면 전체를 인터랙티브 맵처럼 사용 불가능 홈 화면은 앱이 소유한 캔버스가 아님

Apple의 App Extension 문서는 앱 확장이 앱이 아니며, 특정 extension point의 정책을 따르는 잘 정의된 작업만 수행한다고 설명한다. 참고: Understand How an App Extension Works

즉, iOS에서 앱 밖 경험은 자유 캔버스가 아니라, Apple이 제공한 시스템 표면들의 조합이다.


5. 듀오링고식 경험은 어디까지 가능한가

듀오링고는 캐릭터 기반 리텐션의 좋은 참고 사례다.

Duolingo 공식 블로그는 iOS 잠금화면 위젯으로 streak를 추적하는 위젯을 추가했다고 설명한다. 참고: How we developed our addictive and delightful widget - Duolingo Blog

또한 Duolingo는 알림을 개인화한다. 공식 블로그 글에서는 practice reminder에 여러 사전 작성 알림을 사용하고, 학습 언어와 streak 같은 요인에 따라 개인화하며, 알림 문구를 실험한다고 설명한다. 참고: Hi, it's Duo: Meet the AI behind the meme - Duolingo Blog

우리 앱에서 가져갈 점:

  • 캐릭터가 위젯에 자주 보인다.
  • 시간대와 상태에 따라 표정이 바뀐다.
  • 알림이 단순 안내가 아니라 캐릭터 말투를 갖는다.
  • 사용자가 앱을 열기 전에도 "캐릭터가 나를 기다린다"는 느낌을 준다.

우리 앱에서 피할 점:

  • 과한 죄책감
  • 실패/미달성 강조
  • 캐릭터의 협박성 밈
  • 알림 과다 발송

우리 앱식으로 바꾸면 다음과 같다.

듀오링고식 우리 앱식
streak 유지 압박 오늘의 길을 들려달라는 초대
Duo가 화남 캐릭터가 조용히 기다림
연속 학습 강조 사용자의 하루 해석
목표 미달성 경고 오늘은 길이 짧았다는 담담한 반응
위젯 속 마스코트 틈 세계를 들여다보는 작은 창

6. 민성이 아이디어를 구현 경험으로 번역하기

민성이 아이디어의 핵심 문장은 다음이다.

휴대폰 화면과 부품 사이에는 아주 얇은 틈 세계가 있고,
그 틈에서 세 아이가 사용자의 손길을 기다린다.

이걸 iOS 기능으로 번역하면 다음과 같다.

6.1 앱 안에서

앱 본체는 가장 자유로운 공간이다.

여기서는 실제로 "휴대폰 안쪽 틈 세계"를 풀스크린 인터랙티브 공간으로 만들 수 있다.

가능한 연출:

  • 화면 유리 아래에서 빛이 새어 나옴
  • 터치한 위치에 틈이 열림
  • 세 존재의 흔적이 보임
  • 하나에게 손을 내밀면 HealthKit 권한 요청으로 이어짐
  • 걸음수에 따라 둥지와 틈 세계가 복원됨

6.2 홈 화면 위젯에서

홈 화면 위젯은 틈 세계의 "작은 창"으로 쓴다.

가능한 연출:

  • 캐릭터가 화면 아래 작은 틈에서 올려다봄
  • 배경은 스마트폰 내부 부품처럼 보이되 너무 기계적이지 않게 처리
  • 시간대별로 빛 색이 바뀜
  • 걸음수에 따라 캐릭터의 말풍선이 바뀜
  • 버튼으로 "손 흔들기" 또는 "오늘의 길 보기" 가능

위젯 문구 예시:

아침:
오늘은 바깥이 어떤 색일까?

점심:
네 발자국이 조금 들어왔어.
틈 안쪽이 전보다 밝아졌어.

저녁:
오늘 네가 지나온 길을 들려줄래?

6.3 잠금화면에서

잠금화면 위젯은 더 작기 때문에 캐릭터의 존재감을 아이콘과 짧은 문장으로 제한한다.

예시:

  • 작은 캐릭터 얼굴
  • 잔광 42%
  • 길이 조용함
  • 빛 도착

6.4 Dynamic Island에서

Dynamic Island는 산책 중에만 쓰는 것이 좋다.

예시:

  • compact: 캐릭터 눈 또는 작은 빛 아이콘
  • minimal: 잔광 점 하나
  • expanded: 오늘 걸은 거리, 캐릭터 짧은 반응, 종료 버튼

문구:

길의 링크가 열려 있어.
바깥의 빛이 틈으로 들어오는 중.

6.5 알림에서

알림은 캐릭터가 앱 밖으로 말을 거는 수단이다.

예시:

오늘 네 발자국이 조금 늦네.
무리하지 않아도 괜찮아.
다만 바깥이 어떤 날이었는지, 나중에 들려줘.

액션:

  • 오늘 길 보기
  • 나중에
  • 조용히

6.6 Control Center와 Action Button에서

Control은 "캐릭터를 부르는 버튼"처럼 쓸 수 있다.

예시:

  • 길의 링크 시작
  • 틈 열기
  • 오늘 해석
  • 조용 모드

이 기능은 캐릭터의 시각적 존재감보다, 시스템 깊숙한 곳에 앱의 문이 생긴다는 감각이 중요하다.


7. 권장 MVP 구현 전략

MVP에서 모든 OS 표면을 한 번에 만들 필요는 없다.

가장 효과 대비 구현 난이도가 좋은 순서는 다음이다.

1단계: 홈 화면 위젯

가장 먼저 만들어야 한다.

이유:

  • 민성이 아이디어의 "폰 안쪽에 산다"는 감각과 가장 직접적으로 연결된다.
  • 듀오링고식 캐릭터 리텐션을 실험할 수 있다.
  • 위젯 예제가 많고 구현 난이도가 적당하다.

필수 구성:

  • Small/Medium 위젯
  • 캐릭터 이미지
  • 오늘 걸음 기반 상태
  • 짧은 대사
  • 앱 딥링크

가능하면 추가:

  • AppIntent 버튼 인사하기
  • AppIntent 버튼 오늘의 길 보기

2단계: HealthKit 배경 업데이트와 위젯 갱신

위젯이 살아 있는 느낌을 내려면 걸음수 변화가 어느 정도 반영되어야 한다.

구현:

  • HealthKit 권한 요청
  • stepCount 조회
  • HKObserverQuery
  • enableBackgroundDelivery
  • App Group 공유 상태
  • WidgetCenter reload

3단계: 캐릭터 알림

위젯 다음으로 알림이 중요하다.

목표:

  • 듀오링고처럼 캐릭터가 앱 밖에서 말을 거는 느낌
  • 하지만 죄책감 대신 초대와 해석 중심

구현:

  • Local Notification
  • Notification Category
  • Action Buttons
  • 시간대별 메시지 템플릿
  • 걸음 상태별 메시지 분기

4단계: Live Activity

Live Activity는 산책 세션이 생긴 뒤에 붙이는 것이 좋다.

구현:

  • StartWalkIntent
  • WalkLinkActivity
  • Lock Screen UI
  • Dynamic Island compact/minimal/expanded UI
  • 산책 종료 후 앱 해석 화면 딥링크

5단계: Control Widget / Action Button

이건 iOS 18 이상 대상 기능으로, MVP 후반이나 V1.1에 적합하다.

구현:

  • ControlWidget
  • AppIntent
  • 길의 링크 시작
  • 오늘 해석 열기

6단계: 대체 앱 아이콘

캐릭터 선택 이후 사용자가 직접 홈 화면 아이콘을 바꾸게 한다.

구현:

  • alternate app icons
  • 캐릭터별 아이콘
  • 성장 단계별 아이콘은 너무 많이 만들지 않기

8. 권장 아키텍처

OS 표면이 많아지면 상태 관리가 흩어진다. 초반부터 다음 구조를 잡는 것이 좋다.

SwiftUI App
  ├─ CharacterStateStore
  │   ├─ 현재 캐릭터
  │   ├─ 오늘 걸음
  │   ├─ 잔광 레벨
  │   ├─ 마지막 대사
  │   └─ 공간 성장 단계
  │
  ├─ HealthKitStepService
  │   ├─ 권한 요청
  │   ├─ 오늘 걸음 조회
  │   ├─ ObserverQuery
  │   └─ background delivery
  │
  ├─ CharacterMessageService
  │   ├─ 온디바이스 LLM 또는 템플릿
  │   ├─ 시간대/걸음수 기반 메시지
  │   └─ 알림용 짧은 문장 생성
  │
  ├─ NotificationService
  │   ├─ local notification 예약
  │   ├─ action category
  │   └─ deep link 처리
  │
  ├─ WidgetStateExporter
  │   ├─ App Group 저장
  │   ├─ WidgetCenter reload
  │   └─ ControlCenter reload
  │
  └─ AppIntentHandlers
      ├─ 인사하기
      ├─ 오늘의 길 보기
      ├─ 산책 시작
      └─ 조용 모드

Widget Extension
  ├─ HomeScreenWidget
  ├─ LockScreenWidget
  ├─ WalkLiveActivityWidget
  └─ ControlWidget

핵심 원칙:

  • 위젯은 상태를 보여주는 표면이다.
  • 무거운 판단은 앱 본체에서 한다.
  • App Intent는 짧고 결정적인 행동만 수행한다.
  • LLM 응답은 위젯에서 직접 만들지 말고, 앱 본체에서 미리 생성한 짧은 메시지를 저장한다.
  • 모든 앱 밖 표면은 CharacterState라는 단일 상태 모델을 바라본다.

9. 실험해야 할 질문

구현 전에 다음을 실험하는 것이 좋다.

위젯 실험

  • 걸음수 변화 후 위젯이 실제로 얼마나 빨리 갱신되는가?
  • 사용자가 위젯 버튼을 눌렀을 때 App Intent 응답 시간이 어느 정도인가?
  • 캐릭터 이미지가 위젯 크기별로 잘 읽히는가?
  • Small 위젯에서 텍스트가 너무 작아지지 않는가?

알림 실험

  • 하루 몇 번까지 보내도 부담이 적은가?
  • "기다림" 문장이 죄책감으로 읽히지 않는가?
  • 알림 액션 버튼 사용률이 있는가?
  • 사용자가 알림을 끄는 비율이 높지 않은가?

Live Activity 실험

  • 산책 시작/종료 흐름이 자연스러운가?
  • Dynamic Island에서 캐릭터 아이콘이 식별되는가?
  • Live Activity가 걷기 앱처럼 너무 운동 중심으로 보이지 않는가?
  • 종료 후 앱으로 돌아와 해석을 보는 전환이 매끄러운가?

HealthKit 실험

  • stepCount background delivery가 실제 기기에서 얼마나 안정적으로 들어오는가?
  • 앱 미실행 상태에서 어느 정도까지 갱신되는가?
  • 권한 거부 시 위젯과 튜토리얼 경험이 무너지지 않는가?

10. 제품적으로 가장 좋은 조합

현재 기획에 가장 잘 맞는 조합은 다음이다.

앱 본체:
틈 세계의 메인 공간

홈 화면 위젯:
틈 세계를 들여다보는 작은 창

잠금화면 위젯:
캐릭터가 남긴 아주 짧은 신호

알림:
캐릭터가 조심스럽게 말을 거는 순간

Live Activity:
산책 중 열리는 길의 링크

Control Center / Action Button:
길의 링크를 여는 빠른 문

App Intents / Shortcuts:
시스템 안에서 캐릭터에게 말을 거는 통로

이 조합이면 실제 홈 화면 조작은 못 하더라도, 사용자는 다음 감각을 받을 수 있다.

이 캐릭터는 앱 안에만 있는 것이 아니라,
내 폰 곳곳에 아주 작게 스며들어 있다.

11. 최종 판단

민성이 아이디어는 구현 가능성이 있다.

단, 구현 방향을 잘못 잡으면 "iOS에서 불가능한 홈 화면 오버레이"를 붙잡게 된다. 올바른 방향은 Apple이 허용한 시스템 표면을 조합해 캐릭터 존재감을 확장하는 것이다.

최종 권장안은 다음과 같다.

  1. MVP에서는 홈 화면 위젯과 알림부터 만든다.
  2. HealthKit 배경 업데이트로 위젯 상태를 자연스럽게 바꾼다.
  3. 산책 세션이 생기면 Live Activity와 Dynamic Island를 붙인다.
  4. iOS 18 이상에서는 Control Center와 Action Button을 추가한다.
  5. 캐릭터 선택 후 대체 앱 아이콘을 선택하게 해 홈 화면 소유감을 강화한다.
  6. 실제 홈 화면 앱 배치 연동이나 자유 오버레이는 MVP에서 제외한다.

한 문장으로 정리하면 다음이다.

민성이의 "폰 안쪽 틈 세계"는
홈 화면을 해킹하는 방식이 아니라,
WidgetKit, ActivityKit, UserNotifications, App Intents를 묶어
iOS가 허용하는 표면마다 작은 창을 여는 방식으로 구현해야 한다.

참고 링크

GitHub

Apple 공식 문서

제품 레퍼런스