Где и когда нужно получать данные для Watch Complication
После работы с осложнениями в течение нескольких дней я уверенно говорю следующее о процессе обновления обновлений, которые происходят в заданный интервал:
- Системные вызовы
requestedUpdateDidBegin()
- Здесь вы можете определить, изменились ли ваши данные. Если этого не произошло, вашему приложению ничего не нужно делать. Если ваши данные были изменены, вам необходимо позвонить либо:
-
reloadTimelineForComplication
, если все ваши данные должны быть reset.
-
extendTimelineForComplication
, если вам нужно только добавить новые элементы в конец временной шкалы осложнений.
- Примечание: система может фактически называть
requestedUpdateBudgetExhausted()
вместо requestedUpdateDidBegin()
, если вы потратили слишком много вашего бюджета времени на сложность на день. Это и есть причина этого вопроса.
- Если вы вызвали
reloadTimelineForComplication
, система будет вызывать getCurrentTimelineEntryForComplication
(вместе с будущими и прошлыми вариантами, которые получают массивы, в зависимости от ваших настроек времени поездки)
- Это гипотеза, поскольку я еще не тестировал ее, но я верю, что если бы вы назвали
extendTimelineForComplication
, что будет вызван только getTimelineEntriesForComplication(... afterDate date: NSDate ...)
.
- Затем система вызовет
getNextRequestedUpdateDateWithHandler
, чтобы вы могли указать, сколько времени потребуется вашему усложнению для нового обновления.
В документации Apple достаточно ясно, что вы не должны часто запрашивать обновления или слишком много обрабатывать в коде осложнения, или вы исчерпаете свой бюджет времени, и ваше осложнение перестанет обновляться. Итак, мой вопрос: где и когда вы делаете обновление?
В контексте, мой сценарий - это URL с данными возврата, которые изменяются до двух раз в час.
Наиболее очевидным местом для размещения кода выборки URL является func requestedUpdateDidBegin()
Получить данные, сохранить их, а если нет изменений, просто верните их. Если произошли изменения, то продлить или перезагрузить временную шкалу.
Однако выборка URL-адресов может быть дорогостоящей. Альтернативы:
- Поместите код в приложение телефона и отправьте его с помощью
WCSession
, но если пользователь закрывает это приложение, обновления больше не будут выполняться.
- Используйте push-обновления, но это не веб-приложение, поэтому мне некуда отправлять их.
- Очевидно, что я обновлю все данные, когда пользователь взаимодействует с часовым приложением, но теперь это означает, что он обновляется только тогда, когда пользователь использует приложение, что отрицает необходимость усложнения.
Есть ли где-нибудь еще? Могу ли я иметь периодическую функцию в приложении часов, которая не является частью усложнения? Где подходящее место для извлечения данных для обновления осложнений?
Ответы
Ответ 1
Для watchOS 3 Apple рекомендует перейти от использования обновления данных getNextRequestedUpdateDate
для обновления вашего осложнения.
Старый способ для watchOS 2
requestedUpdateDidBegin()
действительно предназначен только для обновления осложнений. Сохранение вашего усложнения (и просмотра приложений) на сегодняшний день обычно связано с гораздо большим, чем перезагрузка временной шкалы (и асинхронное получение данных никогда не вписывается в старый подход).
Новый способ для watchOS 3
Новый и лучший подход заключается в использовании фоновых задач для обновления приложений. Вы можете использовать ряд фоновых задач для schedule и handle ваше расширение приложения проснулось в фоновом режиме, чтобы:
-
Получить новые данные
- обновите свою модель после поступления данных,
- обновите свое усложнение с модели (путем перезагрузки или расширения временной шкалы) и, наконец,
- обновите моментальный снимок док-станции приложения, чтобы отобразить данные на доке.
Вызов каждого задания setTaskCompleted
, как только задача будет завершена.
Другие преимущества использования задач приложения
Одна из ключевых особенностей этого дизайна заключается в том, что расширение часов теперь может обрабатывать различные сценарии переднего плана и фона, которые охватывают:
- первоначально загружать данные при запуске вашего приложения/осложнений,
- обновление данных в фоновом режиме, когда расширение пробуждается фоновой задачей и
- обновление данных на переднем плане, когда пользователь возобновляет ваше приложение из док-станции.
Apple рекомендует использовать каждую предоставленную вам возможность независимо от того, находится ли ваше приложение на переднем плане или на заднем плане, чтобы обновить моментальный снимок вашего приложения, а также док-станцию.
Существуют ли ограничения?
Количество доступных доступных задач в день делится на количество приложений в доке. Чем меньше приложений в доке, тем больше задач может использовать ваше приложение. Чем больше приложений в доке, тем меньше вы можете использовать.
-
Если ваше усложнение активно, ваше приложение можно разбудить не реже четырех раз в час.
-
Если ваше осложнение неактивно, ваше приложение, как ожидается, будет разбужено не реже одного раза в час.
Поскольку ваше приложение теперь работает в фоновом режиме, ожидается, что вы будете эффективно и быстро выполнять фоновые задачи.
Фоновые задачи ограничены количеством процессорного времени и использованием ЦП. Если вы превысите время процессора (или используете более 10% процессора в фоновом режиме), система прекратит ваше приложение (в результате произойдет сбой).
Для получения дополнительной информации
Ответ 2
Изменить: El Tea (op) опубликовал хороший ответ на fooobar.com/info/203160/...
Это интересный вопрос/проблема, и мне было интересно о многом!
По большей части кажется, что когда я работаю над новым осложнением, мне нужно отступить и посмотреть, когда я действительно хочу его обновить. Усвоение "обратного отсчета" могло установить все будущие записи в хронологическом порядке за один раз, когда установлена "дата окончания". Приложение, отображающее текущее состояние веб-службы, может иметь соответствующие данные, хранящиеся в NSUserDefaults
, когда APNS приходит.
Если у вас нет доступа к APNS, не хотите запускать приложение iOS в фоновом режиме и не хотите делать HTTP-запросы от Apple Watch, я могу представить еще 2 варианта.
1) Расписание локальных уведомлений. Хорошо, что ваш Apple Watch должен запускать didReceiveLocalNotification
, но плохая часть - это то, что пользователь получит уведомление, когда вы просто пытаетесь проверить статус без сбоев.
2) Отправьте сообщение iOS через sendMessage(_:replyHandler:errorHandler:)
в свой reloadTimelineForComplication
метод, установив nil
для replyHandler
, чтобы сделать его как можно быстрее:
Вызов этого метода из вашего расширения WatchKit, пока он активен и работает, просыпает соответствующее приложение iOS в фоновом режиме и делает его доступным.
Ваше приложение iOS может выполнять любые сетевые запросы, а затем хранить информацию или нажимать ее на Apple Watch. К сожалению, я не думаю, что расширение часов будет иметь его session.didReceive...
, пока вы его не запустите, но вы можете получить доступ к данным при следующем вызове requestedUpdateDidBegin
.
Как я уже сказал, меня очень интересует то же самое, поэтому отправляйте некоторые мысли назад, и, возможно, мы можем экстраполировать на некоторые лучшие практики здесь.