-
[WidgetKit] WidgetKit 정책과 타임라인(Timeline) 매커니즘/Widget 2025. 5. 21. 15:07반응형
안녕하세요 아렉스입니다 :> 오늘은 WidgetKit 매커니즘에 대해 얘기해 보겠습니다.
전반적인 구조는 2025.05.21 - [/Widget] - [WidgetKit] WidgetKit 간단하게 알아보기 보고 오시면 도움이 됩니다.
위젯은 기존 iOS 앱과 다른 라이프사이클 매커니즘을 가집니다.
또한 정책이 명확하기 때문에, 테스트 간 정책에 따라 정상적인 동작 여부를 구분할 수 있습니다.
WidgetKit 정책
WidgetKit은 배터리와 리소스를 보호하기 위해 위젯 새로고침에 하루 단위 예산을 두고 있습니다.
위젯을 다시 로드하면 CPU, 네트워크, 배터리가 소모되며, 성능 및 배터리 보호를 위해 업데이트 빈도와 횟수를 최소화해야 합니다.
Widget 시스템은 사용자의 행동을 배우고, 학습 기간 동안은 평소보다 더 많은 재로드를 받을 수 있습니다.
학습 기간 이후에는 사용자의 패턴에 맞춰 시스템이 예산을 편성합니다.
WidgetKit은 위젯마다 약 24시간 단위로 예산(새로고침 횟수)을 설정합니다.
위젯이 사용자에게 얼마나 자주, 오래 표시되는가, 마지막 재로드 시점, 앱 활성화 여부 등을 고려해 예산이 조정됩니다.
예산 범위
- 일일 약 40~70회 (시간으로는 15분 ~ 60분 간격) 새로 고침 가능
- 예산 적용 시간은 24시간이며, 사용자의 행동을 배운 후 패턴에 따라 유동적입니다.
예산 소모되지 않는 경우 (무료 갱신)
아래 조건에서는 WidgetKit이 예산을 차감하지 않고 위젯을 새로 고침:
- 앱이 포그라운드 상태
- 앱에 오디오 재생 또는 탐색 세션이 있는 경우
- 버튼/스위치 조작 등 AppIntent 수행
- 애니메이션 중
- 시스템 로케일, 다이나믹 타입, 손쉬운 사용 설정 변경 시
- StandBy 모드 등 시스템 내부 주기로의 자동 새로고침
⚠️ 시스템 설정 변화에 대해 앱이 타임라인을 수동 재요청할 필요 없음
WidgetKit이 강제 재로드하는 경우
- 위젯이 잘 보이지 않는 위치(홈화면 마지막 페이지 등)에 있는 경우 → 재로드 빈도 감소
- 사용자에게 다시 보이는 순간 → 위젯이 다시 새로고침될 수 있음
- 위치 정보 사용 위젯은 위치 변화 발생 시 재로드됨
타임라인 매커니즘
많은 위젯에는 콘텐츠를 업데이트하는 것이 합리적인 예측 가능한 시간을 미리 계획함으로써, WidgetKit은 적절한 시간이 되면 자동으로 위젯을 새로 고칩니다.
위젯을 정의할 때 사용자 지정 TimelineProvider를 구현합니다.
WidgetKit은 Provider로부터 타임라인을 가져와 위젯을 업데이트할 시기를 추적하는 데 사용합니다.
타임라인은 TimelineEntry 객체의 배열입니다.
// ✅ TimelineEntry 프로토콜 채택 struct GrassEntry: TimelineEntry { let date: Date let level: [[Int]] } struct GrassProvider: TimelineProvider { // ✅ 위젯의 뷰를 첫 렌더링시 보여질 미리보기(placeholder) func placeholder(in context: Context) -> GrassEntry { GrassEntry(date: Date(), level: [[]]) } // ✅ 미리보기용 샘플 데이터, context.isPreview 는 기본적으로 true func getSnapshot(in context: Context, completion: @escaping (GrassEntry) -> ()) { let entry = GrassEntry(date: Date(), level: [[]]) completion(entry) } // ✅ 실제 위젯이 timeline을 얻어서 업데이트를 수행하는 메서드 func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) { var entries: [GrassEntry] = [] // Generate a timeline consisting of five entries an hour apart, starting from the current date. let currentDate = Date() for hourOffset in 0 ..< 5 { let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)! let entry = GrassEntry(date: entryDate, level: [[]]) entries.append(entry) } // ✅ 타임라인에 정책과 함께 추가 let timeline = Timeline(entries: entries, policy: .atEnd) completion(timeline) } }
타임라인 정책
정책 설명 .atEnd 마지막 entry의 날짜가 지나면 새 타임라인 요청 .after(Date) 특정 시간 이후 새 타임라인 요청 (예: 2.5시간 뒤 드래곤 등장 등 이벤트 기반) .never 시스템이 자동으로 갱신하지 않음 → 앱이 직접 수동으로 갱신 요청해야 함
(WidgetCenter.shared.reloadTimelines(ofKind:)) 라던지다음 다이어그램은 WidgetKit이 Provider 로부터 타임라인을 요청하여 타임라인 항목에 지정된 각 시간에 위젯을 렌더링하는 방법을 보여줍니다.
앱에서 위젯 업데이트 하는 방법
앱이 위젯의 현재 타임라인에 영향을 미칠 때 WidgetKit에 새 타임라인을 요청하라고 말할 수 있습니다.
특정 유형의 위젯을 다시 로드하려면 앱이 아래와 같이 WidgetCenter를 사용합니다.
1. kind 사용하기: kind 매개 변수는 위젯의 WidgetConfiguration을 만들 때 사용되는 값과 동일한 문자열을 포함합니다.
WidgetCenter.shared.reloadTimelines(ofKind: "some.widget.kind")
2: Intent 매치: 를 사용한 경우 Configuration을 순회하며 매치 된 intent kind 로 업데이트
WidgetCenter.shared.getCurrentConfigurations { result in guard case .success(let widgets) = result else { return } // WidgetInfo 요소 중 매치 되는 것 찾기 위해 순회 if let widget = widgets.first( where: { widget in let intent = widget.configuration as? <IntentName> return intent?.character == characterThatReceivedHealingPotion } ) { WidgetCenter.shared.reloadTimelines(ofKind: widget.kind) } }
3: WidgetBundle 사용하여 모든 위젯 업데이트하기
WidgetCenter.shared.reloadAllTimelines()
공식문서 학습 후 GPT로 요약 및 교차 검증 후 작성 된 게시물 입니다.
잘못된 내용 혹은 이해가 어려운 내용들은 언제든 댓글에서 의견 교환하고 싶습니다!
공감과 구독은 더 나은 글을 작성되는데 큰 도움이 됩니다.읽어주셔서 감사합니다.
https://developer.apple.com/documentation/widgetkit/keeping-a-widget-up-to-date
Keeping a widget up to date | Apple Developer Documentation
Plan your widget’s timeline to show timely, relevant information using dynamic views, and update the timeline when things change.
developer.apple.com
' > Widget' 카테고리의 다른 글
[WidgetKit] WidgetKit 간단하게 알아보기 (2) 2025.05.21