Введение

Пример проекта, демонстрирующий, как взаимодействовать с расширением виджета домашнего экрана, представленным в iOS 14, из области Javascript в приложении React Native.

В первой части мы создадим расширение виджета в нашем примере приложения RN и напишем собственный модуль (мост) для передачи данных из JS в Swift. Затем во 2-й части мы увидим, как использовать данные для настройки виджета и динамически устанавливаемого содержимого. Наконец, в 3-й части мы увидим, как периодически обновлять добавленные виджеты и из приложения.

У нас есть образец «WeatherApp», созданный с использованием React Native (v0.63.3) и Xcode (12.0), который позволяет нам создавать расширение виджета.

Добавить расширение виджета

Откройте приложение WeatherApp в Xcode и выберите «Файл» > «Создать» > «Цель».

Найдите «виджет», найдите «Расширение виджета» в разделе «Расширение приложения», выберите его и нажмите «Далее».

Назовем цель «WeatherWidget». Также убедитесь, что установлен флажок «Включить намерение конфигурации».

(Это создает файл «intentdefinition»). С точки зрения непрофессионала это означает, что если мы хотим открыть экран настройки, долгим нажатием на виджет или домашний экран и выбором опции редактирования виджета. (Конечно, мы хотим, подробнее об этом позже)

Нажмите «Готово», и если вы увидите всплывающее окно с просьбой активировать схему расширения, выберите «Активировать».

Ура! мы добавили расширение виджета на главный экран для нашего приложения погоды. Создайте приложение, и мы увидим имя нашего приложения (WeatherApp) в списке виджетов.

Устранение неполадок!

Если кто-то столкнулся со следующей ошибкой при создании приложения,

следить за этим,

В навигаторе проекта Xcode выберите «WeatherApp», под целями выберите «WeatherWidetExtension» и найдите «путь поиска библиотеки» внутри «Настройки сборки».

Дважды щелкните по нему и, если вы найдете «$(TOOLCHAIN_DIR)/usr/lib/swift-5/$(PLATFORM_NAME)», замените его на «$(TOOLCHAIN_DIR)/usr/lib/swift-5.2/$(PLATFORM_NAME)».

Примерно так должно выглядеть после замены

Записать собственный модуль/мост

Давайте создадим «Swift-файл» внутри группы «WeatherApp» и зададим имя «WeatherWidgetModule», убедитесь, что под целями выбраны «WeatherApp» и «WeatherWidgetExtension».

Xcode спросит, хотим ли мы создать заголовок моста, нажмите «Создать заголовок моста», это позволит нам получить доступ к методам, которые мы собираемся написать в файле swift, внутри файлов target c.

Давайте добавим в файл WeatherWidgetModule.swift наш родной модуль и метод:

import Foundation
@objc(WeatherWidgetModule)
class WeatherWidgetModule: NSObject {
@objc(setWidgetData:)
func setWidgetData(widgetData: NSArray) -> Void {
}
}

Теперь из части JS мы можем передавать данные на сторону виджета, используя описанный выше метод.


useEffect(() => {
WeatherWidgetModule.setWidgetData(data);
}, []);

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

Полный код здесь

Ссылки:

  1. https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/widgets
  2. https://reactnative.dev/docs/native-modules-ios