본문 바로가기
WWDC

WWDC 20 - Create complications for Apple Watch

by vapor3965 2021. 7. 14.

목차


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

     

     

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

     

    Create complications for Apple Watch - WWDC20 - Videos - Apple Developer

    When you add complications to a Watch app, people can access glanceable and up to date information directly from their watch face. We'll...

    developer.apple.com

     


     

    요약

    Timeline을통해 시간마다 complication을 제공한다.

    • CLKComplicationDataSource를 채택하는 class에서 특정메서드를 구현하여 TimelineEntry를 반환한다. 
      • getCurrentTimelineEntry(for:, withHandler:) 메서드를 구현하여 현재시간에맞는 timelineEntry를 반환한다. 
      • getLocalizableSampleTemplate(for:, withHandler:) 메서드를 구현하여, 에디팅모드에서 나타날 complication template를 반환한다. 
    • TimelineEntry에는 dateCLKComplicationTemplate를 필요로한다. 
    • 앱 데이터가변경되어, complication을 변경해야할경우, CLKComplicationServer 의 API를 호출하여 reload한다.

    watch face마다 각기 다른 complication family를 지원한다.

    • complication family마다 다양한 complication template를 지원하고있다. 

    data provider를 통해 특정 데이터가 다양한 사이즈에 유연하게 대응할수있도록 해준다.

    • 각 다양한 complciation family마다 지원하는 provider가 존재한다.
    • CLKDateTextProvider
    • CLKRelatvieDateTextProvider
    • CLKTimeTextProvider
    • CLKTimeIntervalTextProvider
    • CLKSimpleTextProvider
    • CLKImageProvider
    • CLKFullColorImageProvider
    • Guage Provider

    watchOS 7부터는 Graphic Extra Large가 추가되었다.

    👍watchOS7부터는 CLKFullColorImageProvider를 사용하는 complication은 SwiftUI View를 사용할수있다!

     

     


     

     

     

     

    이번 WatchOS7부터는 훨씬 더 쉽게 Complication을 만드는방법을 만들었다.

     

    다음과같은 내용들을 배울것이다. 

     

     

     

    timeline은 Complication의 data를 제공한다. 

    또한 필요한 data를 ClockKit이 app에 요청할수있다.

    또한, 앱에서 새로운 정보가 갱신되었다면, 이를 Clockit에 요청할수있따. 

     

    다음 watch앱을 이용할건데, 

    이는 하와이에서 고래들이 나타난 횟수들을 나타내는 앱이다. 

     

     

    다음과같이, 다른 지역마다 총 3개의 고래관람투어 스케줄이 되어있다. 

     

    위의 스케줄을 ClockKit에 보여질 timeline으로 정의해보면, 아래와같이 표현된다.

    우선, 다른점이몇개있는데, 

    • 각 스케줄들은 범위가아닌, 시작시간만 갖고있다 ( 위에서 Ma'alaea Harbor는 7:30-9:00 이지만, 지금은 범위가아닌, 6:00으로되어있다 ) 
    • 또한, 각 스케줄의 시작시간보다 더 앞선시간을 가지고있다. 
      • 이것은 모든종류의 watch앱들이 이러한것은 아니지만, ( 날씨같은앱은 즉각적인 시간이여야할것이다 )
      • 고래관람앱은 미리 사용자에게 알림을 주기위함이다. 즉, 6:00부터는 7:30-9:00 고래관람이있을예정이다 라고 알리는것. 

     

     

     

    그리고 상단탑의 파란색은 해당시간에맞춰서 complication에 보여질 정보다. 

    시간에따라 바뀌는것을알수있다.

     

     

     

     

    자, 그러면 어떻게 complication에 보여주고자하는 데이터를 어떻게 정의할까? 

     

    Complication families

    우선, complication은 여러그룹( families) 으로 나뉜다 

    • Graphic 그룹들은 watchOS5 부터 소개됐고, 7에서는 Graphic Extra Large가 추가됐다. 
    • watch face 마다 각기 다른 complication 그룹을 사용한다. 

     

     

    • watch face 마다 각기 다른 complication 그룹을 사용한다는 뜻은, 

    Infograph face에서는 Corner, Bezel, circular, 가 가능하고,

    Infograph Modular face에서도 circular, rectangular 가 가능하다. 

     

     

    Complication template는 각 Complication families에서도 다른 레이아웃을 보여주도록한다. 

    • Graphic Circular에서도 Image, StackImage, StackText, OpenGaugeImage 등이있따. 
    • 그러므로, 최대한 watch앱은 다양한 complication families를 지원하는걸 추천한다. 
    • 그리고 각각은 특정 CLKComplciationFamily를 상속받고있다.
    • 공식문서에도 굉장히 잘나와있으므로 참고하길!

     

     

     

     

    TimelineEntry 

    • Date와 ComplicationTemplate로 구성된다.

     

     

    주로 작업하는곳은 CLKComplicationDataSource를 채택한 객체에서 이루어진다. 

    • getCurrentTimelineEntry를 구현하고, handler에 현재timeline entry를 넣어준다. 

     

    몇몇 complication들은 현재 entry로만으로도 충분하지만 ( 지금당장의 정보가 중요한 경우에 )

    미래에 여러개의 entry의 timeline을 제공할수도있다. 

    • getTimelineEndDate 
      • getTimelineEndDate for complication withHandler, which specifies how far in the future you can provide entries
    • getTimelineEntries
      •  all you need to do is provide as many entries as is appropriate for the data you have up to the limit after the given date. The date represents the last timeline entry that we already have, and the limit is so that we only get as many entries as we need at one time. If you provide more, we'll drop all of the entries over the limit.

     

     

     

     

     

    앱에서 데이터가변경된경우, timeline에도 반영하기위해서는 CLKComplicationServer를 이용한다.

    • 기존의 모든 timeline을 없애고 새로하고싶다면, reload
    • 기존의 timeline은 유효하고 추가하고싶다면, extend 
    • 또한 ClockKit은 현재 watch face에서 보여지고잇는 complciation들의 timeline들을 추척하기때문에, 보여지고있는 complication들을  activeComplications을 통해서 확인할수도있다. 
    • 이 메서드에서 CLKComplication을 얻거나, data source 메소드내에서 넘겨주는것외에는 CLKComplication 객체를 직접만들지않는다. 

     

     

     

     


    complciation template를 만들기위해서는 어떻게해야할까? 

    우선 Complciation은 watch screen에 나타내지는데, watch screen은 작은데, complication은 더 작을수밖에없다.

    그러므로, 이러한 제약때문에 같은 글자라도 각각의 complication에 완전히보여질수도, 아닐수도있게된다.

     

    우리는 다양한 data provider를 통해서 몇가지정보들을 제공함으로써, 특정 문자들(날짜 등) 을 다양한 complciation에 유연하게 보여질수도있도록 제공하고있다. 

     

    CLKDateTextProvider

    • Date타입을, 보여주고자하는 특정 날짜, 월,요일 등을 제공함으로써, 다양한 사이즈에 대해 유연하게 만들어준다. 

     

    그럼, 현재시간으로부터 특정시간까지의 남은 시간을 확인하고싶다면? 

    CLKRelativeDateTextProvider

    • 남은시간을 보여주는 Provider

     

     

    이것뿐만아니라 많은 provider가 있다.

     

    단순히 시간만고려하는 TimeTextProvider,

    7:30~9:00과같은 TimeIntervalTextProvider

    그리고 단순히 문자열만 고려하는 SimpleTextProvider

    • 공간이많이 부족한경우에 사용될수있는 짧은 문자열도 제공할수있다. 

     

     

     

     

    ImageProvider도 있는데,  주로 watch face의 색깔에 포커싱하고있다. 

     

    CLKImageProvider

    몇몇 watch face는 단일컬러 또는 멀티컬러 ( 두가지 컬러 - background와 foreground ) 를  적용한다

     

    CLKFullColorImageProvider

    또한, graphic complication families들은 full-color를 적용한다.

    하지만 graphic complication은 tint컬러도 지원하기때문에, 만약 full-color 이미지만 제공했다면, 자동적으로 tint컬러로 맞춰준다. 

    • 대신 tinting behavior을 override하여 CLKImageProvider로 제공할수도있다.

    tint 컬러는 다음세션에서 더 자세하게 !

     

     

     

    Guage Provider

    • 게이지로 데이터를 요약하여 보여준다. 
    • 다양한 complication layout에 맞게 적용된다. ( 코너에있는 게이지와 센터에있는 둥그런 게이지 )
    • 또한 컬러, 그라데이션, 게이지가차고있는 부분들을 커스터마이징가능하다 
    • 그리고 실시간으로 게이지가 업데이트하고자한다면 CLKTimeIntervalGaugeProvider를 통해 start, end date를 설정하면된다. 

     

     

    👍그리고!! watchOS7 부터는 complication에서 SwiftUI를 사용할수있다!

    CLKFullColorImageProvider를 사용하는 complication template는 SwiftUI view도 적용할수있다!

    • 또한 다른 앱에서 사용하던 view를 그대로 재사용할수도있따!! 

    더자세한건 세션을참고!

     

     

     


    그리고 watchOS7 부터는 하나의 워치앱으로부터 여러개의 complication을 제공할수있게됐다  

    지원하는 방법은 DataSource에서 특정메서드를 구현한다.

    getComplicationDescriptors는 현재앱이 지원하고자하는 complication리스트를 정의한다.

    handleSharedComplicationDescriptors는complication들을 포함하고있는 watch face가 공유되어질때 호출된다. 

    Descriptor는 complication을 어떻게 정의할지를 포함한다. 

     

     

     

    Whale App은 여러개의 complication을 갖는데, 

    새로운관측이 나타날때 알려주는 log 와,

    시즌별로 관측된 고래량과

    각위치별로 고래관측량? 

     

     

     

    코드로살펴보면,

    각station별로 데이터를 생성하여, descriptos에 추가한다. 

    이것은 각 위치에따른 관측정보들을 보여주는데 사용될것이다. 

     

    그리고,  log와 시즌별을위한 descriptor를 추가한다. 

    눈에띄는점은 시즌별은 보다 많은 정보를 필요하기때문에 graphicRectangular를 선택했다.

     

    decriptors들을 무효화시키고싶다면, 아래메서드를 호출한다.

    In our Whale Watch example, maybe we only show complications for the user's favorite viewing stations. If they update those, we'll want to update the complications as well.

    If you ever update this list to remove support for a complication that a user currently has on their watch face, we'll continue to ask you for timeline entries for that complication. Do your best to ensure that you can continue to provide useful information in this case.

    Note that this method is different from CLKComplicationServer's reloadTimelineForComplication method. This reloads the list of complications your app offers, where the other reloads a specific complication's timeline.

     

     

     

    늘그랫듯, 유저가 complication을 tap하면, 앱을 launch하게되는데, 

    만약 complicatons의 descriptor가 userActivity와 함께만들어졌다면, launching할때 이를 사용한다.

    그리고, userInfo에 정보를 넣어줄수도있다.

     

     

     

     

     

     

    그러면 ClockKit이 timeline entry들을 요청할때 어떤 complication인지 알수있을까? 

    위에서봤던 timelineEntry들을 만들어내는 메서드를 다시살펴보면, 

    파라미터로, complication이있다.

    이 complication은 다음과같이 프로퍼티들을 갖고있다.  complicationDescriptor와는 다르게 실제 watch face에서 보여지고있는 실제 family를 갖는다. 

    또한, Descriptor에 제공한 정보들 ( userInfo, userActivity ) 들이 userInfo, userActivity에 포함된다. 

     

     

     

    음,watchOS 7이전에는 defaultComplicationIdentifier를 사용했었다고한다.... 

    그러므로, 이것을 체크해서 데이터를제공해야한다... ( 어려워용오) 

    • We have something called the default complication identifier. Is this something you should be using to identify one of your complications? Sure, you could, but that's not its main purpose.

      If you had a complication before watchOS 7, and a user has it on their watch face, or if a user shares a watch face with your complication but chooses to remove the associated data, then you'll get asked about a complication with the identifier CLKDefaultComplicationIdentifier even if you don't explicitly support it in your list of complication descriptors. This is very important. You should support this complication. If not, your users will be wondering why they're seeing a broken complication on their watch face that says it's from your app.

     

    그리고 datasource에서 또다른 메서드가있는데, 

    이는 에디팅모드에서 나타나는 complciation을 요청한다. 

    그러므로 샘플데이터를 포함해야한다. 

    • 각 complication마다 한번만호출되고 캐싱한다. 

     

     

     

    그리고 위에서 계속 createTimelineEntry메서드가있었는데 다음과같다.

    template를 만들고, TimelineEntry에함께넣어 return한다. 

     

    template를 만드는메서드를 살펴보면,

    우선, complication으로부터 station w정보를 가져오는데, 이는 descriptor를 만들때 같이넣어줬던거다. 

    그리고 재사용할데이터들을 만들어준다. ( provider ) 

    마지막으로 default template를 만들어준다. 

     

     

    complciation.family와, identifier에 따라서 각기 다른 template를 반환하는데,

    눈에띄는점은 GraphicRectangular와 GraphicCircular는 SwiftUI view를 사용하여 return하고있다!

    그외의 경우에는 defaultTemplate로반환하고있다. 

     

     

     

    추가적으로 다음세션들을 참고하라. 

     

    댓글