...
본문 바로가기

WWDC

WWDC 20 - Widgets Code-along, part 2: Alternate timelines


  • 세션보면서 정리한 내용입니다. 해석이 잘못된 경우가 있을수있으니 발견하시면 댓글로 남겨주시면 감사하겠습니다🙏🏻

 

https://developer.apple.com/wwdc20/10035

 

Widgets Code-along, part 2: Alternate timelines - WWDC20 - Videos - Apple Developer

Our code-along continues as we help our widget rewrite the future and travel into an alternate timeline. Continue where you left off from...

developer.apple.com

 


 

요약

  • 위젯의 사이즈는 크게 3가지로나뉜다 - small, medium, large 
    • 다양한 사이즈를 지원한다면, view에서도 어떤 사이즈인지 알아야하니까, view안에 @Environment 프로퍼티를 만든다. 
    • 그리고 body는 @ViewBuilder 프로퍼티로 정의하고, Environment를 분기하여, 각 사이즈에맞는 View를 return한다. 
  • timeline provider는 위젯의 핵심적인 엔진으로, 여러 entry들을 뽑아낸다. 
    • 각 타임라인들을 reload 정책을가지고 있다. - atEnd, after( 날짜 ), never 
      • atEnd, after는 타임라인의 마지막 Entry일때 다시 타임라인메서드를 호출한다. 
      • 그리고 중요한점은 시스템에는 수많은 타임라인들이있기때문에, 최대한 지능적으로 스케줄링한다. 즉, atEnd, after는 무조건 보장되는것이아닌, 최소로 보장되는시간이된다
    • 그리고 위젯이 Stack안에서 사용된다면, 시스템은 지능적으로 위젯들을 Rotate시키는데,  이때, 위젯은 relevance를 이용하여 시스템에게 우리의 위젯이 우선적으로 고려해달라고 힌트를줄수있다. 
      • 0~1사이의 실수값을갖는다. 높을수록 높은. 
      • timelineEntry의 옵셔널 프로퍼티다. 
  • 위젯에는 애니메이션, custom interaction( 버튼과같이 )이 없다. 대신 deep link가있다.
    • deep link는 특정뷰를 터치하면 앱으로바로 연결해주는것으로, small사이즈는 하나의 탭지역을갖고, 
    • meidum, large는 Swift link API를 이용하여 여러개의 탭지역을 만들수있다. 
      • 아마 그 API는 .widgetURL 인듯 ? 
  • 위젯에는 사용자가 커스텀할수있또록 configuriaton을 제공한다 이를위해서는 Siri intent 파일이 필요하다. 
    • 해당파일에는 목적에는 Category 가잇고, title, descripton을 지정한다. 
    • 그리고 이제 이 intent파일을 위젯에서사용하기위해서는, 알다시피, 위젯은 Static Configuration이 아닌, IntentConfiguration타입이여야한다.  그리고, 해당 intent파일이름을 사용한다. 
    • 또한, timelineprovider또한 IntentTimelineProvider로 채택해야한다.  마찬가지로 해당 intent파일이름을 사용한다. 
      • 그러므로, 선택된 configuration에 맞게 timeline을 생성해야하므로, 매핑 처리가필요하다. 

 


 

 

요런것들을 살펴볼예정입니다 ~ 

 

 

families는 크게 3가지로 구성된다. 

 

timeline provider는 위젯의 핵심적인 엔진이다.

 

 

provider로부터 하나씩 entry를 뽑아냅니다. 더많이 뽑아내구요. 

그럼 과연 마지막에는 무슨일이일어날까요? 더많은 Entry를 가져오고싶다면요? 

 

그답읍 TimelineReloadPolicy를 선택하는것입니다.

우선 atEnd는 timelnine의 가장 마지막이 보여질때, 업데이트스케줄링을 시작하라고 위젯킷에게 말합니다.

그럼 그때부터 타임라인메서드가 다시호출되고, 더많은 엔트리를 반환하게되죠 

 

 

after는 atEnd와 비슷하게, 날짜를 지정해주는것입니다.

그 날짜에 업데이트 스케줄링을 하라는것이죠. 

아래는 얼마나멀든, 이전엔트리들과 관계없이 오후10시에 스케줄링하라는 뜻입니다. 

 

 

never는 의미로알듯이, 절대 독립적으로 업데이트하지않겠다는 뜻입니다.

그래서 명시적으로 위젯에게 widget centerAPI를 이용해서 reload하라고 해야겠죠.

 

 

 

하지만 생각해보면 특정 reloadpolicy를 가지고 무수히많은 타임라인들이 디바이스에 존재할텐데, 

그러므로, 시스템은 최대한 지능적으로 스케줄업데이트를한다. 

즉 atEnd, after는 무조건 그시간에 업데이트를하는것이아닌, 최소 업데이트할수있는 시간이다. 

 

 

 

위젯은 홈스크린에서 수정이가능할수있다. 

WidgetKit configuration은 SiriKit으로부터 왔고, 이것은 단순히 configruation을 가짐으로써 지능적인 시스템행동에 도움이된다. ? 

configuration의 핵심기술은 INIntents다.  

더자세한건 세션참고. 

 

 

위젯은 절대로 애니메이션과 커스텀interaction이 없다.

하지만 deep link를 할수있다. 

즉, small은 하나의 탭지역을 가지고있고, medium, large는 SwiftUI의 link API를 이용하여 tappable zones을 만들수있다. 

( 즉 노란색들이 deep link가 가능한 구역들 ) 

 

 

 


오케이! 이번세션은 Code로 구현하는거니까,  이전파트에서 진행이후부터 하자.

 

저번파트에서는 small사이즈만 지원해쓴ㄴ데,

이제는 medium도 지원하고싶다.

 

간단하게 supportedFamilies에 systemMedium을 추가해준다. 

 

 

그런데, 이제 small, medium둘다 생겼다. 

그럼 우리는 어떤 뷰가 어떤사이즈로 그려질지를 알아야한다. 

 

WidgetKit은 WidgetFamily environment value를 제공한다.

그러므로, 우리의 main View로 가서, 

@Enviroment 를 추가해주고, 

 

각 family타입으로 view를 반환하기위해

@ViewBuilder를 body에 붙여주고, 

switch 문으로 작성한다.

 

 

 

그럼 preview로 한번봐야지? 

 

이전파트에서는 단순하게 AvartarView로만 보여줬는데,

이제는 EmojiRangerWidgetEntryView로 변경하자.

그리고 previewContext도 medium으로바꿔주고, 

마찬ㄱ지로 placeholderView도 medium으로바꿔주자. 

마찬가지로 PlaceholderView도 변경해주자. 

 

짜잔~ medium 사이즈의 preview가잘나온다! 

 

 

 

자그럼 타임라인을 적용해보자.

우선 우리는 이 팬더가 언제쯤 체력이 다 회복할지를 알고있다. 

그시간이 타이머가되면좋겠다. 

그러므로, 체력이 다회복할때까지 full timeline을 만들면되겠다. 

 

우선 펜더로선택했고,

펜더가 체력이 다회복할때의 시간을 endDate로 설정한다.

그리고 1분주기로 가져올것이다. 

그리고 시작시간을 현재시간으로정한다.

 

그리고 그냥 while문으로 endDate를넘을때까지 1분씩 증가하여 entry를 추가한다.

 

 

 

그리고 위젯이 Stack에 있는경우에 시스템이 지능적으로 rotate시키는데, 

우리는 시스템에게 relevance 라는 것을 이용하여 특정시간에 우리위젯이 우선순위되도록 하라고 힌트를 줄수있다.

한번생각해보자. 언제우리의 위젯이 가장 우선순위가높아져야할까? 

그것은 바로 체력이다찼을때여야하겠다. 그때부터 싸울수있으니까! 

그러므로, 체력을 0~1 사이의 실수값으로표현하여, relevance에 주면되겠다. 

 

TimelineEntry에는 옵셔널타입으로, relevance 프로퍼티가있다. 

 

 

 

 

 


 

그리고 ㅎ 우리는 펜더뿐만아니라 다른 히어로도있다!!

그러므로 다른히어로들도 보고싶다!

위젯에 configuration option에 나타나도록 해보자.

 

 

이렇게 new - file - 클릭

 

siri intent 선택!

 

둘다 target체크

 

 

이렇게만드는데, 

몇가지정보들을 채워넣어야한다. 

왜냐하면 위젯은 정보를 표현해야하기때문에, 우리의 카테고리는 View로한다. 

우선, custom title, description이있고, 

그리고 intent is eligible for widget을 체크하자. 

그리고, paramter로, hero가 있다. hero는 enum타입이다. 

 

 

enum에서 제공하는 값들은 enum에디터에서 제공한다. 

panda, egghead, spouty를 추가하자. 

 

자그럼, 이 intent들을 어떻게사용할수있을까? 

 

그전에!! 우리는 위젯타입을 바꿔야한다. 

static configuration에서 intent configuration으로 변경해야한다. 

위젯에서 IntentConfiguration으로변경해주고,

intent는 아까만든 intent의이름으로 넣어준다. 

 

 

 

그리고 또 바꿔야할게있는데, 

timeprovider를 intent timeline provider로 변경해야한다.

 

IntentTimelineProvider 프로토콜로 바꿔주고, 

그러면 snapshot이랑 timeline메소드는 추가적으로 파라미터를 가진다. - for configruation: 

여기에는 아까 만든 Intent를 넣는다. 

 

 

그러면, 이제 configuration에 선택한 캐릭터를 매핑해줘야하니까, 

다음과같은 intent - 캐릭터타입반환 메서드를 만들어주자. 

 

그러므로, timeline메서드에서 선택된캐릭터를 해당함수로 바꾸준다.

 

이제 실행시키고, default는 팬더고!

 

꾹누르면 Edit widget이나타난다. 

 

 

그럼이제! Configuration을 확인할수있따. 

 

Spouty로 바꾸니!! 짜잔~ 

 

 

 

 


 

자 이제는 위젯에있는 특정캐릭터를 통해서 앱으로 디테일을보고싶어!

매우간단하게 할수있다.

단지 widgetURL modifier를 view에 추가해주면된다.

 

와우...실행해보면 바로 앱으로 들어가지다......!!

 

 

 

끄으으읕!!

 

 

다음세션들을 참고하면 좋다~!