...
본문 바로가기

iOS

WidgetKit 정리


잘못된 내용이나 추가할 개념이 있다면 댓글로 남겨주시면 감사하겠습니다🙏🏻


WidgetKit의 개념을 알아보고자 최근 WWDC들을 공부했습니다.

아직 모르는점도 많지만, 어느정도는 필요한개념들은 습득한 것같습니다.

그래서 하나의 글로 정리해보고자 합니다.

 

아래의 세션들을 참고하여 글로도 정리했으니, 필요하시면 보셔도되지만, 해당 세션을 시청하는걸 추천드립니다.

( 여기서작성하는 글들의 사용방법이나, 구현들은 모두 아래의 글,세션에 포함되어있습니다 ) 

WWDC 20 - Meet WidgetKit

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에 없기도해요. 아마, 그냥 자동적으로 지원하는게 아닐까, 싶습니다. )
  • 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 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