잘못된 내용이나 추가할 개념이 있다면 댓글로 남겨주시면 감사하겠습니다🙏🏻
WidgetKit의 개념을 알아보고자 최근 WWDC들을 공부했습니다.
아직 모르는점도 많지만, 어느정도는 필요한개념들은 습득한 것같습니다.
그래서 하나의 글로 정리해보고자 합니다.
아래의 세션들을 참고하여 글로도 정리했으니, 필요하시면 보셔도되지만, 해당 세션을 시청하는걸 추천드립니다.
( 여기서작성하는 글들의 사용방법이나, 구현들은 모두 아래의 글,세션에 포함되어있습니다 )
WWDC 20 - Widgets Code-along, part 1: The adventure begins
WWDC 20 - Widgets Code-along, part 2: Alternate timelines
WWDC 20 - Widgets Code-along, part 3: Advancing timelines
Widget Link
Widget은 미니앱이아니며, SwiftUI로 만들어지고, Widget에 사용되는 View들은 Stateless한 UI입니다.
- 위젯에는 스크롤, 애니메이션, custom interaction( 컨트롤기능, 버튼과같이 )이 없다.
- 대신 deep link가있다.
- 터치를통하여 앱으로들어갈수있고, 또한 위젯내에서도 관련있는 정보로 앱으로들어갈수있다.
- deep link는 특정뷰를 터치하면 앱으로바로 연결해주는것으로, small사이즈는 하나의 탭지역을갖고,
- meidum, large사이즈는 Swift link API를 이용하여 여러개의 탭지역을 만들수있다.
- Link control을 통해 특정 url을 지정한다.
- 단순하게 링크시켜주는건 .widgetURL을 통해서도 가능하다. 마찬가지로 특정 url을 지정한다.
Widget 타입
Widget의 타입은 크게 두가지로 나뉩니다.
- Static Configuration
- Static은 사용자가 따로 편집할수없는것이며,
- Intent Configuration 는 사용자가 위젯을 편집할수있다.
- intent는 IntentFramework로 구현되며, siri, shorcut과도 통합되어있다.
- 위젯에는 사용자가 커스텀할수있또록 configuriaton을 제공한다 이를위해서는 Sirikit Intent 파일이 필요하다.
- 해당파일에는 목적에는 Category 가잇고, title, descripton을 지정한다.
- 그리고 이제 이 intent파일을 위젯에서사용하기위해서는, 알다시피, 위젯은 Static Configuration이 아닌, IntentConfiguration타입이여야한다. 그리고, 해당 intent파일이름을 사용한다.
- 또한, timelineprovider또한 IntentTimelineProvider로 채택해야한다. 마찬가지로 해당 intent파일이름을 사용한다.
- 그러므로, 선택된 configuration에 맞게 timeline을 생성해야하므로, 매핑 처리가필요하다.
- Intent는 dyanmic 하게도 지원이가능한데, 새로운 target - Intent extension과 file - Sirikit Intent파일이 필요하다.
- Intent파일에서는 Enum대신 Type을 사용한다. 해당 Intent는 자동적으로 INIntent를 채택하는 class가 자동적으로만들어지며, 마찬가지로 ~~IntentHandling 프로토콜도 만들어진다.
- Intent Extension내부에서 해당 프로토콜을 채택하여, provide~ 메소드를 구현하여, 내부적으로 INObjectCollection을 매핑하여 내보낸다.
- timeprovider또한 각 특정 configuration을 따라야합니다. 그러므로, Static configuration으로 구현했다가, Intent Configuration으로 변경하고자한다면 Widget, timeprovider에 사용된 configuration을 모두 바꿔야합니다.
Widget 사이즈
Widget의 사이즈는 크게 3가지로나뉩니다.
- small, medium, large
- default로 모두 가질수있고, 모든 사이즈들을 무조건 지원해야하는건 아니다.
- Widget의 family들을 제한하는 방법은 Widget - body - .supportedFamilies modifier를 이용하면된다.
- Widget이 다양한 사이즈를 지원한다면, view에서도 어떤 사이즈인지 알아야하니까, view안에 @Environment 프로퍼티를 만든다.
- 그리고 body는 @ViewBuilder 프로퍼티로 정의하고, Environment를 분기하여, 각 사이즈에맞는 View를 return한다.
서로다른 Widget지원
하나의 Widget Extension에서 여러개의 다른위젯들을 추가할수있다.
- 여러개의 다른 위젯을 지원하고자한다면, WidgetBundle을 이용한다.
- @main attribute은 하나의프로세스의 하나 main만 존재해야하므로, WidgetBundle을 채택하는 객체에 붙여준다.
Widget 작동원리
Widget은 Widget자체를 보여주는 View와, View에 들어갈 데이터 즉 entry 가 필요하고, 이 entry는 timeline provider에 의해 제공된다.
Widget의 작동원리는 provider에의해 timeline들이 만들어져, timeline을통해서 특정시간에 특정뷰( + timelineEntry ) 를 보여주는 메커니즘을 가진다. provider는 위젯의 핵심적인 엔진이다.
- provider는 특정configuration을 채택하는 Provider로 나뉘고, placeholder, snapshot, timeline등을 만들어낸다.
- placeholder는 위젯이 timeline을 기다리는동안 사용되어지고, 유저정보를 이용하지말자.
- 유저정보를 이용하지않느방법으로는 간단하게 SwiftUI -
.isPlaceholder modifier를 이용하면 손쉽게가능하다.- ( 직접해봤는데 isPlaeholder자체가없어졌더라고요. -ㅁ- 애초에 이제는 PlaceholderView 기본Template에 없기도해요. 아마, 그냥 자동적으로 지원하는게 아닐까, 싶습니다. )
- 유저정보를 이용하지않느방법으로는 간단하게 SwiftUI -
- snapshot은 위젯갤러리에서 한번만 사용되는 entry로 사용된다. ( 또는 placeholder가 사용될수도 있음. )
- timline은 위젯갤러리로부터 홈스크린에 추가되고나서 사용된다.
- 또한 각 timeline 이후에 특정 정책에맞게, 다른 timeline들을 reload할수있다. ( atEnd, after, never )
- reload는 background notification이나, 앱을통해서 WidgentCenter API를 이용하여 강제적으로 reload할수있다.
- atEnd, after는 타임라인의 마지막 Entry일때 다시 타임라인메서드를 호출한다.
- 그리고 중요한점은 시스템에는 수많은 타임라인들이있기때문에, 최대한 지능적으로 스케줄링한다. 즉, atEnd, after는 무조건 보장되는것이아닌, 최소로 보장되는시간이된다.
- 간혹 뷰에 보여줄 데이터가 네트워킹이 필요한경우라면, background URLSession을 이용하고, Widget extension에서는 onBackgroundURLSessionEvents를 통해서 받아오도록한다.
- ⬇️timeline 시각화
- 또한 각 timeline 이후에 특정 정책에맞게, 다른 timeline들을 reload할수있다. ( atEnd, after, never )
- timeline provider는 completion 핸들러를 통해 손쉽게 비동기요청에 대한 데이터를 넣어줄수있다.
- backgroundSession은 app delegate가 따로없지만, WidgetConfiguration - .onBackgroundURLSessionEvents modifier를 통해서 다룰 수 있다.
Widget Reload
Widget reload는 timeline의 reload 정책에따라 reload될 수 있으며,
또한 App을 통해서도 가능하다.
- 직접 App의 포그라운드에서 WidgetCenter의 API를 이용하여 직접 reload를 호출할 수 있다.
- 또는 background notification을 받음으로써 마찬가지로 API를 이용하여 reload를 호출할 수 있다.
Stack Widget
Widget은 홈스크린에 배치되는데, Stack안에서도 배치가가능합니다.
- 이때 Shortcut이나, 특정값을정하여 시스템이 더 지능적으로 특정 위젯이 나타나게할수도있다.
- 시스템은 지능적으로 위젯들을 Rotate시키는데, 이때, 위젯은 relevance를 이용하여 시스템에게 우리의 위젯이 우선적으로 고려해달라고 힌트를줄수있다.
- 0~1사이의 실수값을갖는다. 높을수록 높은.
- timelineEntry의 옵셔널 프로퍼티다.
Widget을 preview로 볼때는, previewContext modifier를 붙여야한다.
'iOS' 카테고리의 다른 글
RxSwift, RxCocoa 정리 (0) | 2021.08.18 |
---|---|
CoreData와 CloudKit 연동하기 (2) | 2021.08.18 |
좌우 스크롤되는 캘린더뷰 만들기( feat: CompositionalLayout ) (0) | 2021.08.09 |
각 주제별 WWDC 참고용 (0) | 2021.07.09 |
Core Data 정리 (0) | 2021.07.04 |