Как сделать свой виджет для iphone

Как создавать собственные виджеты на iPhone с помощью приложения Widgetsmith

С выходом iOS 14 Apple значительно расширила функционал виджетов на iPhone, а также разрешила создавать собственные темы оформления. Это послужило стремительному наполнению App Store сторонними приложениями, которые помогают пользователям кастомизировать главный экран iOS. В этом материале мы расскажем об одном таком приложении – Widgetsmith. Данная разработка значительно упрощает создание собственных виджетов на iPhone.

Приложение Widgetsmith создана Дэвидом Смитом, разработчиком нескольких популярных приложений для Apple Watch и iPhone, включая Watchsmith, Sleep++ и Pedometer++. Концепция программы Widgetsmith заключается в том, что она позволяет создавать настраиваемые и персонализированные виджеты для домашнего экрана iOS 14. При этом приложение еще и активно обновляется – появляются дополнительные опции, иконки и т.д. С ее помощью можно раскрасить виджеты в соответствии с вашими предпочтениями. Как это работает?

Видео:

Как с помощью Widgetsmith настроить виджеты для домашнего экрана iPhone и iPad в iOS 14

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

Сам процесс невероятно прост.

1. Нажмите кнопку «Add Widget» для нужного вам размера виджета.

2. Нажмите на виджет для его настройки.

3. Выберите какого рода информацию вы хотите видеть на главном экране. Вот источники данных, доступные в Widgetsmith (ниже мы привели несколько примеров для добавления виджетов):

  • Пользовательские: фото, фотографии в альбоме.

  • Пользовательские: текст, бланк

  • Календарь
  • Напоминания
  • Погода (платно по подписке)
  • Здоровье и активность
  • Приливы (платно по подписке)
  • Астрономия

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

4. После того, как вы создали виджет для главного экрана iOS 14 в приложении Widgetsmith, вы можете вернуться на главный экран, нажать и удерживать палец для включения режима покачивания иконок, а затем нажать значок «+» в верхнем левом углу.

5. Найдите Widgetsmith в списке приложений, затем выберите размер созданного вами виджета и нажмите кнопку «Добавить виджет».

6. После этого на главный экран iOS будет добавлен виджет от Widgetsmith.

На главном экране iOS 14 вы можете использовать столько виджетов от Widgetsmith, сколько захотите. После того, как вы добавите элемент Widgetsmith нужного вам размера на главный экран, нажмите на него пальцем и удерживайте, затем выберите «Изменить виджет».

7. В появившемся меню выберите вариант «Widget».

Это позволит вам выбрать один из нескольких дизайнов, уже созданных в приложении Widgetsmith. Фактически, каждый виджет домашнего экрана iOS при желании может быть получен от Widgetsmith.

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

8. Для удаления ненужного виджета в приложении Widgetsmith, проведите пальцем справа налево по выбранному и нажмите красную кнопку «Delete».

Источник

Как пользоваться Widgetsmith и создать свои виджеты в iOS 14

С выходом iOS 14 виджеты буквально получили вторую жизнь на iPhone. Если раньше это были небольшие информационные окна в отдельном разделе операционной системы, то сейчас виджеты можно размещать в любом месте экрана, на любом рабочем столе, причем сколько угодно! Но к удивлению популярностью стали пользоваться не столько виджеты от уже установленных приложений (вроде почты, календаря и прочего), а программы, позволяющие создавать собственные виджеты. Одним из самых популярных приложений для создания виджетов оказалось Widgetsmith. Что в нем такого особенного, и как создать свой виджет?

С этим приложением можно сделать какой угодно виджет

Что такое Widgetsmith

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

Первое, что вам нужно сделать, это выбрать, какую информацию вы хотите, чтобы виджет отображал на главном экране. Вот какие данные можно вывести в Widgetsmith:

  • Время;
  • Дата;
  • Пользовательские: фото, текст, альбом;
  • Календарь;
  • Напоминания;
  • Погода;
  • Здоровье и активность;
  • Приливы;
  • Астрономия.

Есть как бесплатные виджеты, так и те, которые доступны только при оформлении подписки на премиальные функции. Подписка стоит 149 рублей в месяц или 1 550 рублей в год.

Виджеты, созданные в Widgetsmith. Хотите так же? Читайте ниже

Как пользоваться Widgetsmith

Процесс создания виджета невероятно прост. Вы просто выбираете размер виджета, который хотите создать, а затем нажимаете на виджет, чтобы настроить его.

Выберите размер и тип виджета

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

Типов виджетов очень много, некоторые бесплатные, другие за деньги

Вот, например, как создать текстовый виджет Widgetsmith. Выбираете размер виджета и настраиваете его: выбираете Text (тип данных), а затем меняете цвет шрифта, фон, тип шрифта — в общем, настраиваете так, как надо.

Создание текстового виджета

Для того, чтобы сделать фото виджет в Widgetsmith, выберите тип «Photo», а затем загрузите свое изображение из библиотеки.

Выберите тип виджета Photo

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

Добавьте виджет на рабочий стол

А если еще добавить к виджетам Widgetsmith собственные иконки, можно вообще изменить рабочий стол на айфоне до неузнаваемости.

Как добавить виджет в iOS 14

После того, как вы создали виджет главного экрана iOS 14 в приложении Widgetsmith, вы можете вернуться на главный экран, нажать на него пару секунд, а затем выбрать значок «+» в верхнем левом углу. Найдите Widgetsmith в списке приложений, затем выберите размер созданного вами виджета.

Читайте также:  Требование ввода пароля iphone

На главном экране iOS 14 вы можете использовать столько виджетов от Widgetsmith, сколько захотите. После того, как вы добавите виджет Widgetsmith на домашний экран, нажмите и удерживайте, выберите «Редактировать виджет» и переключайтесь между всеми виджетами, созданными в приложении Widgetsmith. Каждый виджет на вашем домашнем экране iOS 14 может быть сделан в Widgetsmith, если вы захотите.

Можно сделать несколько виджетов и переключаться между ними

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

Если вы еще не скачали это приложение, можете попробовать по ссылке ниже. Свои рабочие столы можете скидывать в нашем чате в Telegram, интересно, что у вас получится.

Источник

Как создать виджет для iOS 14 (и не удалить его у пользователей при обновлении)

Одно из нововведений в iOS 14 — виджеты. Мы стали готовиться к этому событию задолго до официального релиза, чтобы они появились у пользователей приложения Яндекс уже на старте. В этом посте я расскажу об опыте разработки виджетов в условиях нестабильного бета-окружения, неполной документации и отсутствия готовых решений для возникающих проблем.

Помимо обзорной информации, под катом — истории о том, почему нельзя просто взять и добавить настройки в виджет (спойлер: можно случайно удалить виджет установившим его пользователям), и как даже новейшие Swift-only API иногда страдают от наследия Objective-C. Материал будет полезен как тем, кто привык разбираться во всём новом, находя готовые гайды в интернете, так и тем, кто предпочитает официальную документацию.

Первые шаги

Виджеты — новый тип элемента главного экрана в iOS SpringBoard. Он стал четвёртым по счёту, прервав консервативный период, который длился 10 мажорных релизов системы:

  1. изначально на рабочем пространстве находились только приложения;
  2. в версии 2.1 появилась возможность помещать на него закладки Safari;
  3. В iOS 4 добавилась группировка иконок (новым элементом экрана стала группа).

С помощью виджетов можно отобразить динамически обновляемую информацию. Хорошие примеры: биржевые курсы, ближайшие события из календаря или уровень заряда беспроводных устройств. Мы решили сделать два виджета: один с поиском и актуальной информацией, а другой с прогнозом погоды и картой осадков.

Виджеты бывают трёх размеров: маленький и большой — квадратные, занимают место 4 и 16 обычных иконок; средний — прямоугольный горизонтальный, 2х4 иконки. Мы сфокусировались на разработке маленького и среднего.

Кроме них существует особый тип виджета — смарт-стопка, аналог группы для обычных иконок. В стопку виджеты попадают по желанию системы, ничего специально делать не нужно.

Что делаем для пользователя — разобрались, осталось выяснить, как это делать.

Изучаем особенности API

Apple добавили новый фреймворк для реализации виджетов WidgetKit , который работает вместе с дебютировавшим в iOS 13 SwiftUI :

При этом ограничение на уровне системы типов — не единственное:

  • запрещено использование UIKit (в обычном приложении интеграция UIKit в иерархию SwiftUI возможна с помощью UIViewRepresentable / UIViewControllerRepresentable );
  • недоступно анимирование контента;
  • отсутствует публичный API для добавления полупрозрачности тела виджета (чтобы через него просвечивал фон SpringBoard, как на виджете зарядов батареи);
  • влиять на взаимодействие с пользователем можно только задавая разные области нажатия, как следствие — запрещён любой скролл и не работает модификатор @State (присвоение значения не дает никакого эффекта).

Если добавить запрещённые элементы на UI, вместо них отобразится значок на жёлтом фоне.

На среднем и большом размере виджета с помощью SwiftUI.Link можно разметить области нажатия. При активации размеченной области откроется основное приложение, в котором вызовется метод application(_:open:options:) вашей реализации протокола UIApplicationDelegate . Для маленького размера виджета можно задать только один URL. Делается это с помощью нового модификатора widgetURL(_:) (его можно использовать и для других размеров, но поддерживается только одно использование на один виджет).

Стоит отметить, что взаимодействие с фоновыми загрузками тоже отличается от обычного приложения. UIApplicationDelegate отсутствует, поэтому невозможно реализовать его метод application:handleEventsForBackgroundURLSession:completionHandler: , который до этого был единственной точкой входа обработки произошедших в фоне событий. Вместо него добавлены два метода в обе доступные реализации протокола WidgetConfiguration . Обычные сетевые запросы работают так же, как и в приложении.

Загружаем контент

На виджетах мы чаще всего хотим отображать динамический контент, данные для которого загружаются асинхронно. Во время загрузки необходимо показывать легковесный UI (placeholder, заглушку), который создаётся за максимально короткое время и не вызывает задержек при первом добавлении виджета или изменении настроек. Подобный UI для системного виджета погоды выглядит так:

Чтобы предоставить данные для отображения заглушки, реализуем отдельный метод:

Здесь Self.Entry — заданный разработчиком тип. В нём можно явно сохранять признак того, что требуется именно заглушка, и использовать его при создании экземпляра View . Однако Apple не были бы Apple, если бы не добавили в этот механизм немного магии: к сформированному View неявно применяется модификатор .redacted(reason: .placeholder) , который автоматически «упрощает» иерархию: превращает тексты в полупрозрачные прямоугольники со скругленными краями и убирает битмапы из изображений.

У нашего виджета с «картиной дня» в основном статический контент, и мы хотели сразу отображать его, показывая заглушки только для асинхронно загружающихся элементов, поэтому при создании View нужно было добавить модификатор .unredacted() . Возможно, создатели API делали упор на упрощение расчёта геометрии, чтобы не создавать угрозу плавности работы интерфейса при добавлении виджета, но на практике после того, как мы убрали заглушку, нам не удалось заметить задержек даже на стареньком iPhone 7.

Обновляем содержимое

Содержимое виджета обновляется по pull-модели. Система запрашивает контент, когда считает нужным. Примеры детерминированных моментов запроса контента: открытие галереи виджетов, добавление виджета и изменение настроек. На интервалы обновления можно повлиять с помощью Timeline , задающего массив состояний виджета:

Каждое состояние привязано к определённой дате и может задавать параметр relevance , влияющий на поведение авторотации виджетов в стопке:

Поле policy позволяет выбрать вариант перезапроса Timeline :

  • запросить новый Timeline сразу после отображения последнего состояния,
  • не запрашивать вообще,
  • запросить при наступлении определённой даты.

Эта модель исключает быструю разрядку батареи из-за ошибки в пользовательском коде, ведь он запускается только на ограниченное время, нужное для асинхронного формирования контента. Есть, однако, и существенный минус. В случае, если при запросе обновления отсутствовала возможность получить данные (например, не было интернет-соединения), не получится оперативно сделать новую попытку в момент её восстановления (в случае с отсутствием интернета — с помощью реакции на нотификацию от SCNetworkReachability ). На этот раз Apple не оставили даже традиционного приватного API для собственных приложений: системный погодный виджет надолго остаётся в состоянии заглушки, если добавить его, находясь в авиарежиме. Сгладить проблему можно, уменьшив интервал обновления данных при ошибке.

Читайте также:  Что такое djvu apple

Стоит отметить, что существует механизм обновления содержимого виджетов из родительского приложения:

Он может быть полезен, если контент виджета зависит от действий пользователя в приложении.

Взаимодействуем с основным приложением

Как и в любом App Extension, коммуникация между виджетом и основным приложением возможна с помощью Keychain Sharing. Его дополняет WidgetCenter, который позволяет основному приложению получать информацию об установленных виджетах и обновлять их содержимое (выполнять новые запросы Timeline ) вне очереди. Вот несколько идей, как их можно использовать:

  • аналитика (сбор статистики об установках виджетов пользователями);
  • интерактивный экран со списком установленных виджетов в приложении и конфигурирование с Keychain Sharing;
  • случаи, когда виджет отображает часть состояния приложения, и нужно реагировать на его изменение, вызывая обновление.

Добавляем настройки

История о добавлении настроек в виджет заслуживает отдельного внимания. На видео с WWDC всё выглядит легко, просто и красиво, но, как говорится, теоретически практика должна совпадать с теорией, а в реальности получается наоборот.

Как это выглядит

После добавления возможности конфигурирования виджета в меню действий, по долгому нажатию можно увидеть соответствующий пункт:

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

Как это работает

Настройки реализованы при помощи интентов. Изначально интенты были добавлены как часть SiriKit. Они классифицируют действия пользователя, которые система может распознать, в зависимости от окружающего контекста: например, подобрать ответ на обращение к Siri или предложить построить маршрут на работу при посадке в машину утром в будний день. Для обработки действия, описываемого интентом, создается специальный Intents Extension. Этот механизм натянули на глобус переиспользовали для реализации виджетов. Чтобы описать настройки виджета, нужно создать интент с типом View и отметить галочку Intent is eligible for widgets . В обучающем видео с WWDC 2020 выступающий скромно говорит, что «пока что» отключит галочки, отвечающие за использование интента в Siri и приложении Shortcuts, хотя не вполне очевидно, зачем описание настроек виджета может хотя бы теоретически там понадобиться. Также непонятно, почему тип интента не фиксируется на View , когда он отмечен для виджета, ведь остальные типы в этом случае неработоспособны.

Технически в качестве описания интентов и их вспомогательных типов выступает XML-файл с расширением intentdefinition , который особым образом интерпретируется Xcode-ом. Xcode предоставляет красивый UI для редактирования содержимого. Из файла при помощи утилиты intentbuilderc генерируется код на Swift с включённым экспортом в Objective-C. Этот код включается в сборку таргетов, использующих описанные в нём интенты. Экспорт в Objective-C здесь неспроста: iOS использует гибкость его рантайма для межпроцессного взаимодействия и хранения настроек. Чтобы это было возможно, в каждый бандл, использующий сгенерированные интенты, кладётся оригинал файла intentdefinition . Весь этот автомагичный механизм в духе Apple, как это часто бывает, не обошёлся без подводных камней.

Что с миграцией?

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

Допустим, вы сделали несколько разных виджетов, у которых изначально были одинаковые настройки, поэтому вы использовали один интент на всех. А если виджет один, но поддерживает несколько размерностей, API просто-таки подталкивает к тому, чтобы применить общий тип интента:

Позже вам могут понадобиться уникальные настройки в одном из виджетов. Например, переключение между прогнозом погоды по дням и часам. Оно имеет смысл только для среднего и, возможно, большого размеров, ведь на маленький размер (2х2 иконки) ленту прогноза не уместить. Чтобы добавить настройку, нужно использовать отдельный тип интента для типов/размеров виджетов с уникальными пунктами в настройках. Здесь-то и кроется подвох.

На момент написания статьи (актуальный релиз iOS 14.3) не было механизма, который позволял бы изменить тип интента для установленного виджета. Тут бы пригодилась возможность скрыть виджет из галереи, чтобы у пользователей старой версии сохранялась её работоспособность, а новые виджеты добавлялись с раздельными классами настроек, но такой роскоши Apple нам не предоставили. Пришлось выбирать из двух зол:

  • удалить старый виджет всем установившим его пользователям,
  • оставить два в целом одинаковых виджета в галерее: один с обновлённым набором настроек и второй для поддержания работоспособности уже установленных.

Если вы набрали заметную пользовательскую базу со старой версией, первый вариант, скорее всего, не для вас. Мы успели его случайно проверить, потеряв в итоге несколько тысяч установок. Во втором случае есть дополнительная неприятность: при изменении настроек для конкретного размера виджета нет способа сохранить их порядок по возрастанию. Старая версия навсегда останется в галерее с фиксированным порядком от малого до большого размеров, а новый виджет придётся добавлять либо в начало, либо в конец этой группы.

Однако есть чуть более сложный, но действенный путь. При запуске основного приложения мы можем узнать, какие виджеты установлены у пользователя, и с помощью keychain sharing передать эту информацию в сам виджет. Так можно безопасно исключить из списка «старые» виджеты, если они у пользователя не стоят. Это не решает проблему полностью, но оставляет галерею «чистой» для новых пользователей и позволяет исключить новые установки нежелательных версий, чтобы со временем полностью от них избавиться.

Good old stringly typed way

Упоминая гибкость рантайма Objective-C, я подразумевал всеми любимый stringly typed подход: по информации из intentdefinition система генерирует описанные в нём классы непосредственно в рантайме, причём (предположительно) делает это также и в системном процессе, отвечающем за управление основным экраном iOS (Springboard). Если у интента есть подгружаемые с помощью Intents Extension данные, тот же подход используется для формирования имён методов, вызываемых системой. Для каждого описанного типа интента генерируется протокол *IntentHandling , Objective-C-селекторы которого формируются с учётом названий пользовательских типов:

В чём же здесь проблема, спросите вы? Ведь stringly typed подход издавна используется в экосистеме Apple, существуют даже API, которые невозможно использовать без KVO — одной из вершин мысли в сфере гибкости рантайма. О том, к чему всё это привело и почему мы решали возникшую проблему целый рабочий день, я и расскажу.

Мы решили добавить в настройки выбор города, чтобы пользователь мог получить актуальные данные без геолокации или создать несколько экземпляров виджета для разных городов. Казалось бы, задача тривиальная: создаём интент, называем его CitySearch , не подозревая, что потом не сможем переименовать его при добавлении в настройку новых пунктов. Создаём новый тип данных City , чтобы реализовать поиск по префиксу в Intents Extension . Проверяем: выбираем в новом пункте настроек город, подтверждаем выбор касанием по свободной области и видим размытый фон вместо экрана SpringBoard.

Читайте также:  Чтобы был значок iphone

Кнопка Home возвращает нормальное состояние домашнего экрана, но выбранный город сбрасывается. Это же ранняя бета iOS, верно? Может, нужно заново добавить виджет, чтобы всё заработало, а к релизу баг починят? Сказано — сделано. Удаляем виджет, открываем список приложений, выбираем наше и… видим чёрный экран с индикатором загрузки по центру — признак упавшего процесса SpringBoard, отвечающего за отображение главного пользовательского экрана iOS. MacOS показывает, что, собственно, случилось (разработка в основном ведётся на симуляторе):

Возможно, это проблема симулятора. Проверяем на устройстве — картина та же. Не забываем, что это первый опыт добавления настройки в виджет, поэтому мы лихорадочно ищем, в какой момент свернули не туда: пересматриваем видео с WWDC, скрупулёзно изучаем код. Ведь не может же быть такого, что тривиальный happy case добавления настройки в виджет не работает! Спустя часы безуспешных расследований скачиваем пример от Apple — всё в порядке, настройки открываются, выбор сохраняется и применяется. Полностью воссоздаём ситуацию с динамической подгрузкой вариантов через Intents Extension , проблема не воспроизводится. Отличия два — названия интента и типа данных его единственного поля. А что, если… да ну, бред какой-то. Меняем название типа интента на наше — полёт нормальный. Переименовываем тип данных в City , бинго! Проблему воспроизвели, решение понятно: добавляем к City префикс и/или суффикс, и радуемся работающей настройке. А теперь несколько строк о том, что произошло.

Интерфейс настроек виджета запускается в отдельном процессе, поэтому исключение внутри него не приводит к падению всего интерфейса. А вот открытие галереи (или, по крайней мере, подготовка к её открытию) происходит в SpringBoard, что оказалось фатально. Насколько можно судить по косвенным признакам, в исполняемом файле SpringBoard уже есть Objective-C класс City , из-за которого произошёл конфликт имён в рантайме (скорее всего подсистема, конструирующая классы из intentdefinition в рантайме, увидела, что City существует и создавать его заново не нужно). К сожалению, в документации Apple ничего не сказано о необходимости добавлять префиксы к именам интентов или описанных для них типов данных. Пока для нас остались открытыми несколько вопросов:

  • Возможен ли конфликт типов данных из разных приложений?
  • Каким образом можно было быстро диагностировать проблему?
  • Насколько всё это влияет на безопасность?
  • Какого чёрта, Apple?

В последней на момент написания статьи версии iOS (14.3) проблема не исправлена.

Локализуем строки

Выдохнув после неожиданной заминки с поиском городов, переходим к локализации настроек. Делается это классическим способом через .strings -файлы для каждого из поддерживаемых языков. Не самым классическим при этом является формат файла. Его содержимое выглядит примерно так:

zkSKoF , nTpy85 и pMOT5M — идентификаторы строковых значений, автоматически сгенерированные при редактировании интента через Xcode. И здесь не обошлось без трудностей. Например, наши внутренние инструменты не умеют выгружать данные в таком формате, поэтому обновлять переводы настроек приходится вручную. Да и человекочитаемость формата оставляет желать лучшего, из-за чего страдают ревью пулл-реквестов.

Другие подводные камни

Кэширование UI

Система склонна довольно агрессивно кэшировать UI виджета. Это относится и к заглушкам, и к обычному состоянию: если изменить настройки, а потом вернуть их в прежний стейт, интерфейс восстановится из кэша без обращения к пользовательскому процессу. Такая особенность даёт неожиданный бонус в виде устойчивости к критическим ошибкам, приводящим к падению. Единственным последствием от краша процесса будет пропуск обновления контента, в то время как в старом Today-виджете появлялась надпись Unable to load.

Но кэширование, к сожалению, нельзя отключить. Настройки для разработчиков позволяют лишь убрать ограничение на количество показов в автоматически ротирующемся стеке виджетов. Из-за этого возникают неудобства при отладке. К счастью, кэш обычного состояния сбрасывается при переустановке приложения, даже если оно не изменилось (полезный пункт меню Xcode — Run Without Building ). Это не относится к заглушке: будьте готовы перезагрузить симулятор или устройство, чтобы система показала изменения в дизайне.

Как это обычно бывает с новой функциональностью, механизм виджетов не обошёлся без багов. Особую остроту ситуации добавила разработка в условиях бета-релизов iOS. Мы не знали точно, какие из проблем Apple успеет исправить до релиза, а какие — нет.

Информация об установленных виджетах

Нам было важно знать, не пропали ли усилия с выпуском виджета к релизу iOS 14 даром, поэтому мы хотели получить данные о количестве пользователей новой функциональности. К нашему ужасу, вплоть до последнего выпуска беты сохранялся баг API, отдававшего информацию об установленных экземплярах: после удаления виджеты отображались как установленные до перезагрузки устройства. Главный сценарий был исправлен в GM-сборке, но в iOS 14.3 сохранилась проблема с менее популярной последовательностью действий. Если удалить основное приложение, не удаляя виджеты, а потом снова установить его, виджеты на SpringBoard не вернутся, но в WidgetCenter будут отображаться как установленные до перезагрузки устройства.

Анимации переходов

Я уже упоминал, что роль пользовательского кода в отображении виджетов максимально пассивна, и за многие вещи отвечает система. Одно из таких мест — отображение настроек и переход между ними и основным состоянием. К сожалению, в iOS 14.3 после изменения любой настройки до сих пор около секунды вместо плейсхолдера отображается фон. Он будет чёрным, если на телефоне установлена тёмная тема, или белым, если светлая:

Геолокация

В нашем случае от местоположения пользователя зависела информация, отображаемая в виджете. Оказалось, и тут всё непросто — виджет отправляет отдельный запрос на разрешение от пользователя, а в Xcode 12 beta 5 в CLLocationManager появилось новое поле:

По его значению можно понять, дал ли пользователь согласие на определение местоположения. Проблема заключалась в том, что запрос разрешения, которое влияет на значение этого флага, выполняется системой без участия пользовательского кода, и в первой версии этот механизм работал не так, как планировали разработчики API. Диалоговое окно и пункт меню в системных настройках, позволяющий изменить решение о выдаче доступа, не показывались при первом добавлении виджета. Была вторая половина августа, релиз намечался на первую половину сентября, поэтому ситуация получилась не из приятных: невозможно было полноценно разрабатывать и тестировать основной сценарий использования продукта. Исправленные Xcode 12/iOS 14 beta 6 появились только 25 августа.

Заключение

Быть среди первых разработчиков, открывающих пользователям новые возможности — всегда интересно. Однако этот путь чреват непредвиденными проблемами и набиванием шишек на ровном месте из-за несовершенства документации и самой платформы. Надеюсь, статья станет для вас не только забавным описанием злоключений первопроходцев, но и принесёт пользу: облегчит работу или вдохновит в трудную минуту.

Источник

Оцените статью