Статьи

Введение в ClockKit

На WWDC 2015 Apple объявила о своем первом крупном обновлении программного обеспечения Apple Watch, watchOS 2 . Это новое обновление принесло с собой множество новых API-интерфейсов и функций для разработчиков, включая собственные приложения, доступ к большему количеству оборудования Apple Watch и улучшенную связь с родительским приложением iOS.

В этом уроке я собираюсь показать вам, как воспользоваться еще одной новой функцией — возможностью создавать пользовательские усложнения часов с помощью платформы ClockKit. Это руководство требует, чтобы вы работали с Xcode 7 в OS X Yosemite (10.10) или новее.

Если вы еще не знаете, осложнения Apple Watch — это небольшие элементы интерфейса, которые отображают информацию на циферблате.

Apple Watch осложнения

На приведенном выше снимке экрана показано, как пять сложностей отображаются на циферблате Modular в дополнение к времени в верхнем правом углу.

Создайте новый проект в Xcode, используя watchOS> Приложение> Приложение iOS с шаблоном приложения WatchKit .

Шаблон проекта

Затем настройте проект, как показано ниже, убедитесь, что флажок « Включить сложность» установлен.

Варианты проекта

Как только Xcode создаст ваш проект, откройте расширение WatchKit ClockKit Введение в Навигаторе проекта . Вы увидите новый раздел « Конфигурация осложнений », как показано ниже.

Сложности Конфигурация

Пять флажков в разделе Поддерживаемые семейства представляют различные семейства сложностей, которые поддерживает ваше приложение. В этом уроке мы сосредоточимся на семействе Modular Large . Вы можете снять другие флажки на данный момент.

Модульный выбор большой семьи

Как говорится в Apple Руководство по переходу на watchOS 2 настоятельно рекомендует, чтобы ваше приложение поддерживало все пять семейств. На следующем рисунке показано, где используются эти разные семейства.

Apple Watch семьи осложнений
Изображение предоставлено: Apple watchOS 2 Руководство по переходу

Чтобы научить вас использовать ClockKit, вы создадите простое усложнение, которое показывает время, название и жанр поддельных телевизионных шоу на определенной станции в течение дня.

Для начала откройте ComplicationController.swift в папке Расширение WatchKit Введение ClockKit . Xcode автоматически создал этот файл для вас. Он содержит класс ComplicationController , который соответствует и реализует протокол CLKComplicationDataSource .

Методы, связанные с этим протоколом, — это то, как вы предоставляете данные ClockKit о тех сложностях, которые вы хотите показать. Методы протокола содержат обработчик, который необходимо вызвать для передачи данных обратно в ClockKit.

Предоставляя данные для ClockKit, вы делаете это в виде временной шкалы. Вы делаете это, заполняя временную шкалу вашей сложности объектами данных, которые связаны с определенным моментом времени. Эти объекты данных моделируются классом CLKComplicationTimelineEntry . Когда достигается определенный момент времени, ClockKit автоматически отображает правильный контент для вашего приложения.

Часы вашей временной шкалы извлекаются и кэшируются с помощью ClockKit задолго до того времени, когда они предназначены для отображения. Это означает, что данные должны быть в состоянии быть извлечены и запланированы заранее. Каждое приложение имеет ограниченный бюджет времени для обновления своего контента в фоновом режиме. Другими словами, осложнения не являются заменой push-уведомлений или центра уведомлений.

Основным преимуществом предоставления данных таким способом является поддержание превосходного взаимодействия с пользователем. Содержание для каждого осложнения сразу же доступно, когда пользователь поднимает ее запястье. Одним из других преимуществ использования этой модели данных временной шкалы является возможность легко использовать новую функцию Time Travel в watchOS 2. Это когда пользователь поворачивает цифровую головку, глядя на циферблат, и данные о сложностях отражают время. это было путешествовано .

В вашем коде под меткой Конфигурация временной шкалы вы увидите четыре метода, необходимых для настройки временной шкалы. Чтобы сделать это руководство простым и понятным, мы будем поддерживать только пересылку во времени и предоставлять данные на срок до 24 часов. Для этого обновили реализацию первых трех методов, как показано ниже.

01
02
03
04
05
06
07
08
09
10
11
func getSupportedTimeTravelDirectionsForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTimeTravelDirections) -> Void) {
    handler(.Forward)
}
     
func getTimelineStartDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
    handler(NSDate())
}
     
func getTimelineEndDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
    handler(NSDate(timeIntervalSinceNow: (60 * 60 * 24)))
}

Четвертый метод в разделе Конфигурация getPrivacyBehaviorForComplication(_:withHandler:) , getPrivacyBehaviorForComplication(_:withHandler:) , используется, чтобы указать, хотите ли вы, чтобы содержание вашего усложнения отображалось, когда устройство заблокировано или нет. Значение по умолчанию, переданное в обработчик ShowOnLockScreen , означает, что данные всегда будут видны.

Прокрутите до конца класса ComplicationController и найдите метод getPlaceHolderTemplateForComplication(_:withHandler:) . В этом методе вы создаете и передаете CLKComplicationTemplate обратно в обработчик для данных, которые вы хотите показать. В этом руководстве вы собираетесь использовать шаблон CLKComplicationTemplateModularLargeStandardBody , который отображает три строки текста. Для каждого телешоу эти три строки будут:

  • время начала и окончания
  • имя
  • жанр

Для пяти семейств усложнений доступно довольно много шаблонов. На следующем рисунке показаны доступные шаблоны и выделены те, которые мы будем использовать в этом руководстве.

Доступные шаблоны усложнения часов
Image Credit: Создание осложнений с помощью ClockKit (WWDC 2015)

Поскольку на дисплее часов ограничено пространство для содержимого, тем более что при небольших размерах сложностей с циферблатом вы предоставляете текстовые данные для ClockKit, используя объекты CLKTextProvider . Эти провайдеры стремятся избежать усечения контента, что приводит к плохому пользовательскому опыту. С этими поставщиками текста вы описываете свои намерения относительно того, какой контент вы хотите отобразить, а затем ClockKit обрабатывает окончательное форматирование для вас.

Например, если вы хотите отобразить дату в своем усложнении, вы используете CLKDateTextProvider с указанной датой и набором единиц (месяц, день, час и т. Д.). Это правильно отформатирует дату для доступного места. В качестве примера можно привести дату «четверг, 22 октября» и возможность отформатировать ее в:

  • Четверг, 22 октября
  • Четверг, 22 октября
  • 22 октября
  • 22

Полный список поставщиков текста и шаблонов, доступных в ClockKit, можно найти в справочнике Apple ClockKit Framework .

Теперь, когда вы знаете об основных шаблонах и поставщиках текста, вы готовы создать шаблон для вашей сложности. В getPlaceHolderTemplateForComplication(_:withHandler:) добавьте следующий код:

01
02
03
04
05
06
07
08
09
10
func getPlaceholderTemplateForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTemplate?) -> Void) {
    // This method will be called once per supported complication, and the results will be cached
    let template = CLKComplicationTemplateModularLargeStandardBody()
     
    template.headerTextProvider = CLKTimeIntervalTextProvider(startDate: NSDate(), endDate: NSDate(timeIntervalSinceNow: 60 * 60 * 1.5))
    template.body1TextProvider = CLKSimpleTextProvider(text: «Show Name», shortText: «Name»)
    template.body2TextProvider = CLKSimpleTextProvider(text: «Show Genre», shortText: nil)
     
    handler(template)
}

С помощью этого кода вы создаете шаблон Standard Body для семейства Modular Large и предоставляете ему три поставщика текста. Объекты CLKSimpleTextProvider должны быть простыми. CLKTimeIntervalTextProvider принимает две даты и форматирует их в строку, например, «10:00 — 3:30 вечера» или «1: 00-2: 45 вечера».

Теперь, когда мы настроили нашу временную шкалу и предоставили ClockKit шаблон для нашего усложнения, мы можем наконец проверить результаты нашей работы. В левом верхнем углу окна Xcode выберите цель сложности и один из доступных симуляторов. Нажмите кнопку воспроизведения, чтобы создать и запустить приложение.

Выбор цели осложнения

Когда запустится симулятор Apple Watch, вам, скорее всего, будет представлен следующий циферблат:

Начальный циферблат

Чтобы проверить свое осложнение, вам нужно выполнить несколько шагов.

Нажмите Ctrl + Shift + 2, чтобы смоделировать касание силы и нажмите на циферблат.

Выбор часового циферблата

Нажмите Ctrl + Shift + 1 , проведите вправо к модульной поверхности и нажмите кнопку « Настроить» .

Модульный вариант лица

Проведите пальцем вправо, коснитесь средней сложности и прокрутите вниз, используя трекпад или мышь для имитации цифровой короны.

Сборщик осложнений

Снова смоделируйте принудительное касание, чтобы вернуться к выбору циферблата и выбрать Модульное лицо.

Модульное лицо с вашим осложнением

Поздравляю. Вы только что получили самое первое усложнение ClockKit, которое появилось на циферблате Apple Watch. Теперь пришло время начать заполнять его некоторыми (поддельными) данными.

Прежде чем создавать какие-либо записи временной шкалы для нашего усложнения, мы сначала собираемся создать структуру Show чтобы легко моделировать наши данные, а затем создать значения этого нового типа. Добавьте следующий фрагмент кода в ComplicationController.swift перед началом определения класса ComplicationController .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
struct Show {
    var name: String
    var shortName: String?
    var genre: String
     
    var startDate: NSDate
    var length: NSTimeInterval
}
 
let hour: NSTimeInterval = 60 * 60
let shows = [
    Show(name: «Into the Wild», shortName: «Into Wild», genre: «Documentary», startDate: NSDate(), length: hour * 1.5),
    Show(name: «24/7», shortName: nil, genre: «Drama», startDate: NSDate(timeIntervalSinceNow: hour * 1.5), length: hour),
    Show(name: «How to become rich», shortName: «Become Rich», genre: «Documentary», startDate: NSDate(timeIntervalSinceNow: hour * 2.5), length: hour * 3),
    Show(name: «NET Daily», shortName: nil, genre: «News», startDate: NSDate(timeIntervalSinceNow: hour * 5.5), length: hour)
]

Как видите, мы создаем структуру Show и создаем статический массив, который содержит четыре шоу. Вы будете использовать этот массив в качестве источника данных вашей сложности.

В классе ComplicationController найдите метод getCurrentTimelineEntryForComplication(_:withHandler:) и добавьте в него следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: ((CLKComplicationTimelineEntry?) -> Void)) {
    // Call the handler with the current timeline entry
     
    let show = shows[0]
    let template = CLKComplicationTemplateModularLargeStandardBody()
     
    template.headerTextProvider = CLKTimeIntervalTextProvider(startDate: show.startDate, endDate: NSDate(timeInterval: show.length, sinceDate: show.startDate))
    template.body1TextProvider = CLKSimpleTextProvider(text: show.name, shortText: show.shortName)
    template.body2TextProvider = CLKSimpleTextProvider(text: show.genre, shortText: nil)
     
    let entry = CLKComplicationTimelineEntry(date: NSDate(timeInterval: hour * -0.25, sinceDate: show.startDate), complicationTemplate: template)
    handler(entry)
}

Сначала вы создаете шаблон усложнения, как вы делали раньше, и наполняете его содержимым. Затем вы создаете объект CLKComplicationTimelineEntry с двумя параметрами:

  • свидание
  • шаблон

Дата, которую вы здесь указываете, — это место, где эта запись будет расположена на временной шкале и показана пользователю. Для нашего приложения мы даем нашей временной шкале дату за пятнадцать минут до начала шоу, чтобы оно отображалось на часах пользователя как раз перед началом шоу.

Затем вам нужно предоставить ClockKit со всеми другими шоу, которые вы создали для вашей сложности. Это делается в getTimelineEntriesForComplication(_:afterDate:limit:withHandler:) . Параметр limit в этом методе таков, что одно приложение не может перегружать кэш ClockKit данными и точно знает, сколько записей временной шкалы необходимо предоставить.

Добавьте следующий код в метод getTimelineEntriesForComplication(_:afterDate:limit:withHandler:) в ComplicationController.swift :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
func getTimelineEntriesForComplication(complication: CLKComplication, afterDate date: NSDate, limit: Int, withHandler handler: (([CLKComplicationTimelineEntry]?) -> Void)) {
    // Call the handler with the timeline entries after to the given date
    
    var entries: [CLKComplicationTimelineEntry] = []
     
    for show in shows
    {
        if entries.count < limit && show.startDate.timeIntervalSinceDate(date) > 0
        {
            let template = CLKComplicationTemplateModularLargeStandardBody()
             
            template.headerTextProvider = CLKTimeIntervalTextProvider(startDate: show.startDate, endDate: NSDate(timeInterval: show.length, sinceDate: show.startDate))
            template.body1TextProvider = CLKSimpleTextProvider(text: show.name, shortText: show.shortName)
            template.body2TextProvider = CLKSimpleTextProvider(text: show.genre, shortText: nil)
             
            let entry = CLKComplicationTimelineEntry(date: NSDate(timeInterval: hour * -0.25, sinceDate: show.startDate), complicationTemplate: template)
            entries.append(entry)
        }
    }
     
    handler(entries)
}

Сначала вы создаете пустой массив объектов CLKComplicationTimelineEntry . Затем вы перебираете шоу, которые вы создали ранее. Для каждого шоу, если оно начинается после даты, предоставленной ClockKit, и лимит записей не был превышен, вы создаете шаблон и добавляете его в массив.

В конце этого метода вы вызываете обработчик с вашим массивом. Передача nil или пустого массива в обработчик сообщит ClockKit, что у вас больше нет данных для предоставления, и он прекратит запрашивать ваш объект CLKComplicationDataSource пока не потребуется больше данных.

С этими методами вы готовы увидеть, что ваше осложнение закончено. Нажмите кнопку воспроизведения, чтобы создать и запустить приложение. Когда симулятор запустится впервые, вы увидите, как усложняются показы данных для первого шоу, которое вы создали.

Осложнение, показывающее первое шоу

Если вы затем прокрутите трекпадом или мышью, чтобы войти в режим Time Travel, вы увидите, что другие созданные вами шоу отображаются вашим усложнением в нужный момент времени.

Путешествие во времени

В этом уроке вы узнали об основах платформы ClockKit и о том, как создать нестандартную усложнение циферблата для Apple Watch. Сюда входили пять семейств усложнений, базовые шаблоны и поставщики текста, а также данные на временной шкале.

В вашем усложнении вы также встроили поддержку функции часового путешествия watchOS 2 и добавляли новые данные по мере прохождения времени. Как всегда, если у вас есть какие-либо комментарии или вопросы, оставьте их в комментариях ниже.