Сигнал за спойлер: React Native не може да се използва на самата джаджа.

Цел: Научете как да създавате естествена джаджа и да споделяте информация с вашето приложение React Native.

TL;DR: Проверете целия код и следвайте ангажиментите тук.

Разширена функция: Препоръчва се да познавате добре React Native и да имате известен опит с разработката за Android/iOS.

Джаджата е важно допълнение към приложението и често е много желана функция. За съжаление, не можете да използвате React Native директно, за да създадете джаджата. Защо? Тъй като iOS има ограничение от 16 MB памет за разширения на приложения и React Native би поел по-голямата част от нея от самото начало. Повярвай ми, опитах.

Така че алтернативата е да се създаде всяка джаджа нативно с Java на Android и Swift на iOS. И обикновено се нуждаете от джаджата, за да можете да споделяте информация с основното приложение - в този случай с приложението React Native. Този урок ще ви покаже как може да се постигне това.

Нарекох проекта ReactNativeCreateWidgetTutorial,и ще изглежда по следния начин:

iOS

1. Създайте файловете на джаджата

Създайте приспособлението (на iOS се нарича Today Extension), като отворите файла на работното си пространство в Xcode и щракнете върху File › New › Target:

Изберете Today Extension и щракнете върху Next:

Дайте му име и изберете предпочитания от вас език. В този случай ще избера Swift. Щракнете върху Готово:

Ако Xcode поиска да активира схемата, щракнете върху Активиране.

Трябва да видите папката Widget във вашия проект:

Сега трябва да видите уиджета на вашия екран с уиджети и вече можете да го активирате:

Сега нека проверим структурата на джаджата. Отидете в папката Widget и щракнете върху файла с сценария. Кликнете върху бутона за помощник-редактор (този с два кръга в горния десен ъгъл на екрана):

Можете да видите, че има две функции, наречени viewDidLoadиwidgetPerformUpdate. ФункциятаviewDidLoad се изпълнява всеки път, когато потребителят превключи към екрана с джаджи. Така че това е мястото, където трябва да инициализирате променливи, етикети или изгледи. ФункциятаwidgetPerformUpdate се извиква винаги, когато трябва да актуализирате съдържанието на притурката.

2. Персонализирайте потребителския интерфейс на джаджата

Можете също така да видите, че има етикет с текст „Здравей свят“. Нека персонализираме този етикет, като го плъзнете в нашия код. Щракнете с десния бутон върху етикета и плъзнете New Referencing Outletдиректно към кода вътре в класа.

Трябва да видите препратката в кода по следния начин:

Нека променим текста на етикета във функцията viewDidLoad:

override func viewDidLoad() {
 super.viewDidLoad()
 // Do any additional setup after loading the view from its nib.
 //ADD THIS LINE 
 textLabel.text = "My first Widget"
}

Ако стартирате приложението, трябва да видите, че етикетът е инициализиран правилно:

Съвет: Можете да стартирате приспособлението, без да стартирате цялото приложение, като отидете на Xcode и изберете приспособлението като цел и след това щракнете върху изпълнение:

3. Създайте канал за комуникация между изпълнимия модул и приложението React Native

Добре, сега забавната част. Нека нашето приложение React Native контролира какво показва джаджата. За да направим това, трябва да приложим начин приложението React Native да комуникира с джаджата. Ще направим това чрез споделено хранилище между джаджата и приложението React Native. Това може да се постигне с помощта на UserDefaultsiOSродниямодул.

Ще накараме приложението React Native да пише до UserDefaultsи ще накараме джаджата да чете от него. Първият проблем, който откриваме, е, че няма официален начин на React Native за взаимодействие с UserDefaults,ине намерих добра библиотека за това. Така че нека внедрим това сами, като създадем мост между React Native и родния iOS.

Първо, ще създадем споделено пространство в нашето приложение, което ще позволи комуникация между изпълнимия модул и приложението. Това може да стане с App Groups, които се намират в раздела Capabilities.

Нека го активираме и след това изберете група или добавете такава, ако е празна:

Добре, след като имаме активирани App Groups, нека внедрим начин за React Native да пише в UserDefaults чрез създаване на собствен мост.

Сизберете вашия проект и щракнете с десния бутон, за да добавите нов файл:

Изберете Cocoa Touch Class и щракнете върху Next:

Тъй като това е хранилище, което ще бъде споделено от уиджета и приложението React Native, нека го наречем SharedStorage. Изберете Objective-C и щракнете върху следващия:

Сега трябва да видите новите файлове във вашия проект:

Нека редактираме тези файлове. Първо копирайте това във файла SharedStorage.h:

И това във файла SharedStorage.m:

Важно: Променете името на групата (group.com.createwidget.pimenta) на това, което сте създали в App Groups.

Сега можете да се обадите на SharedStorage в React Native. Както можете да видите в кода, всичко, което прави, е да получава JSON и да го съхранява в хранилището UserDefaults.

4. Контролирайте съдържанието на уиджета с приложението React Native

От страна на React Native, нека импортираме модула:

import { NativeModules } from 'react-native';
const SharedStorage = NativeModules.SharedStorage;

И тогава нека изпратим някои данни в хранилището:

SharedStorage.set(
 JSON.stringify({text: 'This is data from the React Native app'})
);

Можете да направите това, например, на вашия App.js или където сметнете за подходящо, за да зададете данните на вашия React Native код:

Сега всичко, което остава, е джаджата да прочете данните и да ги вмъкне в потребителския интерфейс. Ще свържем приспособлението към UserDefaults, ще прочетем данните му и след това ще отпечатаме данните на „Hello World“textLabel.

Отидете до вашия TodayViewController.swiftфайл в папката Widget и редактирайте viewDidLoad функцията по следния начин:

//CHANGE THE GROUP NAME
let userDefaults = UserDefaults(suiteName:"group.com.createwidget.pimenta")
override func viewDidLoad() {
 super.viewDidLoad()
 // Do any additional setup after loading the view from its nib.
 //ADD THIS
 do{
  let shared = userDefaults?.string(forKey: "data")
  if(shared != nil){
   let data = try JSONDecoder().decode(Shared.self, from: shared!.data(using: .utf8)!)
   textLabel.text = data.text
  }
 }catch{
  print(error)
 }
}

Можете да проверите целия файл тук.

Важно: Променете името на групата (group.com.createwidget.pimenta) на това, което сте създали в App Groups.

Нека да стартираме приложението и да проверим изпълнимия модул (имайте предвид, че трябва да стартирате и отворите приложението, за да му позволите да напише SharedStorage):

И това е всичко за iOS — сега към частта за Android.

Android

1. Създайте файловете на джаджата

Отворете папката Android в Android Studio. След това в Android Studio щракнете с десния бутон върху res › New › Widget › App Widget:

Наименувайте и конфигурирайте своята джаджа и щракнете върху Готово:

Следващият прозорец ще покаже няколко файла, които ще бъдат добавени към проекта. Файлът Widget.java е мястото, където ще кодираме поведението на джаджата. Останалите файлове са мястото, където ще внедрим компонентите на потребителския интерфейс на джаджата. Щракнете върху Добавяне:

Сега, ако стартирате приложението, трябва да видите наличната джаджа:

Забележка: Ако първо сте направили урока за iOS, коментирайте редовете, където сте извикали SharedStorage във вашия React Native код, тъй като той все още не е внедрен в Android и ще предизвика грешка.

Добре, сега, след като джаджата работи, нека я персонализираме малко.

2. Персонализирайте потребителския интерфейс на джаджата

В Android Studio отворете папката на приложението си и изберете файла res -› оформление -› widget.xml:

Това отваря оформлението на вашата джаджа. Както можете да видите, има текстов изглед с текста „ПРИМЕР“. Можете да видите повече подробности, ако щракнете върху него:

Нека променим текста на етикета. Както можете да видите в свойствата на етикета, текстът се отнася до „@string/appwidget_text.“ Това се намира на res › values ​​› strings.xml. Отворете този файл и ще видите дефинирания текст:

Ако промените текста от „ПРИМЕР“ на „ЗДРАВЕЙТЕ“, запазете файла и стартирайте приложението отново. Ще бъде отразено в джаджата. Хайде да го направим:

Добре, сега знаем как да персонализираме джаджата. След това нека приложим начин да направите това чрез приложението React Native.

3. Създайте канал за комуникация между уиджета и приложението React Native

Добре, сега отново забавната част. Нека нашето приложение React Native контролира какво показва джаджата. За да направим това, трябва да приложим начин приложението React Native да комуникира с джаджата. Ще направим това чрез споделено хранилище между джаджата и приложението React Native. Това може да се постигне с помощта на SharedPreferencesродния за Androidмодул.

Ще накараме приложението React Native да пише в SharedPreferences и ще накараме уиджета да чете от него. Първият проблем, който откриваме, е, че няма официален начин на React Native за взаимодействие с SharedPreferences,ине намерих добра библиотека за това. Така че нека приложим това сами.

За да извикаме SharedPreferences, ще създадем мост между React Native и родния Android.

Добавете два файла към вашия проект до MainActivity.java, наречени SharedStorage.java иSharedStoragePackager.java:

Копирайте следното във вашия SharedStoragePackager.java файл:

И това във вашия SharedStorage.java файл:

Important: Променете името на пакета com.reactnativecreatewidgettutorial на свое. А също и Widget.class към името на вашия клас джаджа.

Сега можете да се обадите на SharedStorage на React Native. Както можете да видите в кода, всичко, което прави, е да получи JSON и да го съхрани в хранилището SharedPreferences и след това да каже на джаджата да се актуализира.

За да знае Android, че вашият модул съществува, добавете го към списъка с пакети във вашия MainApplication.java файл.

new SharedStoragePackager()

4. Контролирайте съдържанието на уиджета с приложението React Native

От страна на React Native, нека импортираме модула.

Забележка:Ако вече сте променили кода на React Native, пропуснете тази част.

import { NativeModules } from 'react-native';
const SharedStorage = NativeModules.SharedStorage;

И тогава нека изпратим някои данни в хранилището:

SharedStorage.set(
 JSON.stringify({text: 'This is data from the React Native app'})
);

Можете да направите това, например, на вашия App.js или където сметнете за подходящо да зададете данните на вашия React Native код:

Сега всичко, което остава, е джаджата да прочете данните и да ги вмъкне в потребителския интерфейс. Ще свържем приспособлението към SharedPreferences, ще прочетем данните му и след това ще отпечатаме данните върху етикета „HELLO“.

Отидете до вашия Widget.javaфайл в папката Widget и импортирайте следните модули:

import android.content.SharedPreferences;
import org.json.JSONException;
import org.json.JSONObject;

Сега променете функцията updateAppWidget по следния начин:

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
 
 try {
  SharedPreferences sharedPref = context.getSharedPreferences("DATA", Context.MODE_PRIVATE);
  String appString = sharedPref.getString("appData", "{\"text\":'no data'}");
  JSONObject appData = new JSONObject(appString);
  // Construct the RemoteViews object
  RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
  views.setTextViewText(R.id.appwidget_text, appData.getString("text"));
  // Instruct the widget manager to update the widget
  appWidgetManager.updateAppWidget(appWidgetId, views);
 }catch (JSONException e) {
  e.printStackTrace();
 }
}

Можете да проверите целия файл тук.

Ние модифицираме функцията updateAppWidget, коятое отговорна за актуализирането на съдържанието на притурката, за да накара притурката да чете от SharedPreferences db и да отпечатва данните върху текстовия етикет.

Това е – сега приложението React Native контролира съдържанието на джаджата. Нека да стартираме приложението и да проверим изпълнимия модул (имайте предвид, че трябва да стартирате и отворите приложението, за да му позволите да пише в SharedStorage):

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

Резултати

Код:Проверете целия код тук.

Надявам се този урок да ви е помогнал.