일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- fcm
- Project
- spring
- Flutter
- SwiftUI
- Delegate Pattern
- Sendbird
- Swift
- coreml
- ios
- task.yield()
- tabman
- Apple Developer Academy
- github
- app intents
- watchkit
- UIStackView
- Coding Test
- widgetkit
- Tuist
- WWDC22
- backend
- cloud functions
- UITableView
- UIDatePicker
- swift concurrency
- 코테
- createml
- Firebase
- Complication
- Today
- Total
azhy의 iOS 이야기
[iOS] WidgetKit[2] - TimelineEntry, TimelineProvider 본문
2022년 7월 18일에 작성됨
지난 글에 이어서 진행됩니다.
샘플 위젯을 만들고 실행까지 시켜봤으니 한 단계 더 나아갈 시간입니다.
예시로 제공되는 코드를 보면 Provider와 SimpleEntry에 TimelineProvider, TimelineEntry 가 채택되어 있습니다.
Time이라는 개념이 Widget에서 엄청 중요한 역할을 합니다.
WidgetKit은 그림과 같이 작동합니다.
그림을 통해 예를 들면 9시, 9시 30분, 10시 5분이라는 시간을 지정해 놓으면 WidgetKit은 그 시간에 맞춰 그 시간의 View를 Widget으로 전송하여 업데이트시켜줍니다.
왜 이렇게 동작을 하냐? 위젯을 사용하는데 로딩이 걸린다? 사용하는 사람이 과연 있을까요..? 그래서 업데이트할 시간을 정해놓고 그 시간에 맞게 위젯을 업데이트시켜주는 것 같습니다.
TimelineEntry
공식문서의 TimelineEntry 정의를 간단히 해석하면 위젯을 표시할 날짜를 지정, 위젯 콘텐츠의 현재 관련성이라고 해석됩니다.
기본적으로 TimelineEntry는 기본적으로 프로토콜이고 date 프로퍼티를 필수로 요구합니다. 이 date는 위 그림의 예시로 따지면 9시, 9시 30분, 10시 5분이 date 프로퍼티가 됩니다. 필수가 아닌 optional 프로퍼티인 relevance도 있지만, 중요한지는 잘 모르겠네요.. 궁금하신 분들은 공식문서를 통해 한번 알아보면 좋을 거 같습니다.
솔직히 TimelineEntry date가 엄청 중요하다 느껴져서 "TimelineEntry는 date라는 필수 프로퍼티를 가지는 프로토콜이고 이 date는 위젯을 업데이트하는 시간을 담고 있다." 요정도 개념만 잡고 넘어가도 충분할 것 같습니다.
TimelineProvider
공식문서에서 TimelineProvider 정의를 "위젯의 업데이트할 시기를 WidgetKit에 알려준다."라고 정의하고 있습니다.
한 마디로 WidgetKit이 Provider에 업데이트할 시간, TimeLine을 요청합니다. 요청을 받은 Provider는 TimeLine을 WidgetKit에 제공하는 것이죠. TimelineEntry과 마찬가지로 TimelineProvider 도 프로토콜입니다.
그림을 보면 이해가 조금 더 잘됩니다. 처음에 WidgetKit은 Provider에게 TimeLine을 요청합니다.
그럼 이 메서드가 불리게 됩니다.
이 코드로 예를 들면 ( 0..<5 -> 0...5 ) 현재 Date를 만들고 0...5 까지 date를 추가해서 넘겨줍니다. 그리고 .hour, 한 시간 단위로 render 하는 코드입니다.
예를 들어 현재 시간이 3시면 [3시, 4시, 5시, 6시, 7시] 가 date로 담겨서 그다음에 reload 되는 코드입니다.
제가 실제로 테스트를 해본 결과는
0...5 + byAdding: .hour - 5시간마다 업데이트 - 현재시간이 3시면 [3시, 4시, 5시, 6시, 7시] 지나고 8시에 reload
0...5 + byAdding: .minute - 5분마다 업데이트 - 현재시간이 3시 5분이면 [5분, 6분, 7분, 8분, 9분] 지나고 10분에 reload
이렇게 돌아가는 것 같습니다.
그리고 정확하게 시간대로 업데이트되는 게 아니라 어느 정도 지나고 나서 업데이트되는 오차가 존재했습니다.
만약 1분마다 위젯을 업데이트하고 싶으면 0..<1 + byAdding: .minute 이렇게 세팅하면 됩니다.
그리고 byAdding 부분에는 초 단위도 존재하고 day, year 등 다양한 케이스가 있으니 본인이 필요한 케이스를 넣어주시면 됩니다.
( 아마도 앱 다운로드받은 시간기준으로 widget이 reload 되는 것 같습니다. 예를 들면 0...5 + byAdding: .minute 케이스에서 3시 8분에 앱을 다운로드 받으면 [8분, 9분, 10분, 11분, 12분] 다음 13분에 reload. 저도 확실하지 않아서 만약 틀렸다면 댓글로 알려주세요! )
TimelineReloadPolicy
자 그럼 [3시, 4시, 5시, 6시, 7시] date가 넘겨지고 7시가 지나면 위젯이 업데이트가 안되나..?라고 생각이 듭니다.
위 그림을 자세히 보시면 Refresh: .atEnd, Refresh: .never 가 보이실 겁니다. 이게 무슨 뜻이냐? 공식문서를 보면 자세히 알 수 있는데 새로고침 정책에는 총 3가지가 있습니다.
atEnd
타임라인의 마지막 날짜가 지난 후 WidgetKit이 새 타임라인을 요청하도록 지정하는 정책입니다.
[3시, 4시, 5시, 6시, 7시] 로 date가 세팅이 되고 7시가 지나면 그다음 타임라인을 요청합니다. 그럼 [8시, 9시, 10시, 11시, 12시] 를 요청하게 되는 것이죠. atEnd로 policy 를 세팅하면 이렇게 타임라인이 끝나더라도 그 다음 타임라인을 요청하기 때문에 임의로 멈추지 않는 이상 계속 돌아가게 됩니다.
after(Date)
WidgetKit이 새 타임라인을 요청할 미래 날짜를 지정하는 정책입니다.
그림을 보면 쉽게 이해할 수 있습니다.
after(2 hr)라고 세팅을 해놨으니 TimeLine 마지막 시간인 3hr 이 끝나면 바로 새로운 타임라인을 요청하는 게 아니라 2시간 뒤에 타임라인을 요청하는 모습을 볼 수 있습니다.
never
never를 쓰면 WidgetCenter를 사용하여 WidgetKit에 새로운 타임라인 요청이 들어올 때까지 타임라인을 요청하지 않습니다.
이렇게 date를 담은 entry와 policy까지 세팅을 한 TimeLine을 만들어서 completion 넘기면 원하는 시간에 자동으로 업데이트하는 위젯을 만들 수 있습니다.
Widget Center
사용자가 구성한 Widget 리스트를 포함하고 Widget Timeline을 다시 로드하는 데 사용되는 객체인데, 아직 사용해보지도 않아서 추후에 사용해 보고 수정하겠습니다. WidgetKit (3) - WidgetCenter Zedd님이 잘 설명해 놓으셔서 궁금하신 분들은 한번 들어가서 읽어보시면 좋을 거 같습니다!
'iOS' 카테고리의 다른 글
[iOS] WidgetKit[4] - Widget View 바로 업데이트 시키기 (0) | 2024.11.12 |
---|---|
[iOS] WidgetKit[3] - App과 Extension, UserDefaults 공유하기 + Realm DB 공유 (0) | 2024.11.12 |
[iOS] WidgetKit[1] - 개념 및 기본, WidgetConfiguration (0) | 2024.11.12 |
[iOS] swift, Error Domain=NSCocoaErrorDomain Code=4099~ 해결법 (0) | 2024.11.12 |
[iOS] Struct와 Class 의 공통점과 차이점 (0) | 2024.11.12 |