Где и когда получить данные для Watch Complication
После нескольких дней работы с осложнениями я с уверенностью говорю следующее о процессе обновления для обновлений, которые происходят с заданным интервалом:
- Системные вызовы
requestedUpdateDidBegin()
- Здесь вы можете определить, изменились ли ваши данные. Если это не так, ваше приложение не должно ничего делать. Если ваши данные изменились, вам нужно позвонить либо:
reloadTimelineForComplication
если все ваши данные должны быть сброшены.extendTimelineForComplication
если вам нужно только добавить новые предметы в конце временной шкалы осложнений.
- Примечание: система может фактически вызывать
requestedUpdateBudgetExhausted()
вместоrequestedUpdateDidBegin()
если вы потратили слишком много времени вашего осложнения на день. Это причина этого вопроса.
- Здесь вы можете определить, изменились ли ваши данные. Если это не так, ваше приложение не должно ничего делать. Если ваши данные изменились, вам нужно позвонить либо:
- Если вы позвонили
reloadTimelineForComplication
, система позвонитgetCurrentTimelineEntryForComplication
(вместе с будущими и прошлыми вариантами, которые получают массивы, в зависимости от настроек путешествия во времени) - Это предположение, так как я еще не проверял его, но я верю, что если вы позвонили
extendTimelineForComplication
что толькоgetTimelineEntriesForComplication(... afterDate date: NSDate ...)
будет называться. - Затем система позвонит
getNextRequestedUpdateDateWithHandler
так что вы можете указать, сколько времени, пока ваше осложнение требует нового обновления.
В документации Apple совершенно ясно, что вы не должны слишком часто запрашивать обновления или слишком много обрабатывать в коде сложности, иначе вы исчерпаете свой временной бюджет, и ваши сложности перестанут обновляться. Итак, мой вопрос: где и когда вы делаете обновление?
Для контекста, мой сценарий - это URL с возвращаемыми данными, который изменяется до двух раз в час.
Наиболее очевидное место, куда можно поместить код извлечения URL-адреса: func requestedUpdateDidBegin()
Получить данные, сохранить их, и если нет изменений, просто верните. Если произошли изменения, продлите или перезагрузите график.
Однако получение URL-адреса может быть дорогостоящим. Альтернативы:
- Поместите код в приложение телефона и отправьте его с
WCSession
, но если пользователь закроет это приложение, обновления больше не будут происходить. - Используйте push-обновления, но это не веб-приложение, поэтому мне некуда их отправлять.
- Очевидно, что я обновлю все данные, когда пользователь взаимодействует с приложением часов, но теперь это означает, что они обновляются только тогда, когда пользователь использует приложение, что устраняет необходимость в усложнении.
Есть еще где-нибудь? Могу ли я иметь периодическую функцию в приложении для часов, которая не является частью осложнения? Где находится правильное место для получения данных для обновления осложнений?
2 ответа
Для watchOS 3 Apple рекомендует вам отказаться от использования источника данных усложнения getNextRequestedUpdateDate
запланированное обновление, чтобы обновить вашу сложность.
Старый способ для watchOS 2
requestedUpdateDidBegin()
действительно предназначен только для обновления усложнения. Поддержание вашей сложности (и отслеживание приложения) в актуальном состоянии обычно включает в себя гораздо больше, чем перезагрузка временной шкалы (и асинхронное получение данных никогда не вписывается в старый подход).
Новый способ для watchOS 3
Новый и лучший подход заключается в использовании задач приложения фонового обновления. Вы можете использовать ряд фоновых задач для планирования и обработки расширения вашего приложения в фоновом режиме, чтобы:
Получить новые данные
- используя WKWatchConnectivityRefreshBackgroundTask для получения данных с телефона, или
- использование WKURLSessionRefreshBackgroundTask для загрузки данных с сервера
- обновить вашу модель, как только данные поступят,
- обновите усложнение модели (перезагрузив или увеличив временную шкалу) и, наконец,
- обновите снимок док-станции вашего приложения, чтобы показать данные на док-станции
Назовите каждую задачуsetTaskCompleted
метод, как только задача завершена.
Другие преимущества использования задач приложения
Одной из ключевых особенностей этого дизайна является то, что расширение часов теперь может обрабатывать различные сценарии переднего и заднего плана, которые охватывают:
- Первоначальная загрузка данных, когда начинается ваше приложение / осложнение,
- обновление данных в фоновом режиме, когда расширение разбужено фоновой задачей, и
- обновление данных на переднем плане, когда пользователь возобновляет ваше приложение из док-станции.
Apple рекомендует использовать каждую предоставленную вам возможность независимо от того, находится ли ваше приложение на переднем или заднем плане, чтобы постоянно обновлять снимок сложности, приложения и дока.
Есть ли ограничения?
Общее количество доступных задач в день делится на количество приложений в доке. Чем меньше приложений в доке, тем больше задач может использовать ваше приложение. Чем больше приложений в доке, тем меньше вы можете использовать.
Если ваше осложнение активно, ваше приложение может просыпаться как минимум четыре раза в час.
Если ваши осложнения не активны, ваше приложение гарантированно просыпается не реже одного раза в час.
Поскольку ваше приложение теперь работает в фоновом режиме, ожидается, что вы эффективно и быстро выполните фоновые задачи.
Фоновые задачи ограничены количеством процессорного времени и разрешенным использованием процессора. Если вы превышаете время ЦП (или используете более 10% ЦП в фоновом режиме), система завершит работу вашего приложения (что приведет к сбою).
Для дополнительной информации
Хорошее введение, объясняющее, когда и зачем обновлять ваше приложение для часов, описано в статье "Разработка великолепных возможностей Apple Watch".
В частности, сеанс " Поддержание актуальности приложения для часов" охватывает все, что вам нужно знать, чтобы постоянно обновлять снимок сложности, приложения и док-станции.
Пример кода WatchBackgroundRefresh демонстрирует, как использовать
WKRefreshBackgroundTask
обновить приложения WatchKit в фоновом режиме.
Изменить: El Tea (op) опубликовал хороший ответ на /questions/5148402/kakova-posledovatelnost-obnovleniya-dannyih-ob-oslozhneniyah-dlya-apple-watch/5148412#5148412
Это интересный вопрос / проблема, и мне было интересно о том же самом!
По большей части кажется, что когда я работаю над новым осложнением, мне нужно отступить назад и посмотреть, когда я действительно хочу его обновить. Сложность "обратного отсчета" может установить все будущие записи временной шкалы за один раз, когда установлена "дата окончания". В приложении, отображающем текущее состояние веб-службы, могут храниться соответствующие данные в 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
,
Как я уже сказал, я очень заинтересован в том же, поэтому оставьте свои мысли и, возможно, мы можем экстраполировать некоторые лучшие практики здесь.