Shipmonk: Jak udělat z Reactu iOS aplikaci
Vyvíjíte aplikaci v Reactu a chcete vydat mobilní appku bez toho, abyste museli všechno přepisovat? Řešením by mohl být WebKit na iOS, který umožňuje komunikaci mezi nativní aplikací a JavaScriptem.
Jak to funguje v praxi?
Pro Shipmonk jsme měli za úkol vyvinout mobilní aplikaci. Shipmonk je logistická firma a má i své vlastní sklady, kde zboží skladují před tím, než ho odešlou ke koncovému zákazníkovi. Zároveň chtějí mít své sklady co nejvíce moderní a digitálně udržitelné (i proto o pomoc poprosili nás). Naším úkolem bylo integrovat React aplikaci, kterou si vyvíjí interně, do iOS a Android a zároveň jim nechat nad vývojem aplikace co největší možnou kontrolu.
Každého slušného mobilního vývojáře teď napadne, že pokud chceme implementovat WebView, respektive WKWebView z WebKitu, budeme mít “prohlížeč” na celou obrazovku. Ale co když React aplikace bude chtít využít hardware mobilu, spouštět kameru, komunikovat s Bluetooth zařízením a tak dál? Jak vlastně funguje komunikace mezi dvěma v podstatě rozdílnými aplikacemi? To zkusím stručně vysvětlit v tomhle blogu.
Native ⏩️ React
Importujeme WebKit do projektu, vytváříme WebView a povolíme mu komunikaci s JavaScriptem, zobrazíme ho na celou obrazovku a jsme hotovi. Jednoduché, ne? Odteď můžeme kdykoli volat libovolný JS kód pomocí metody evaluateJavaScript(“{your JS code goes here}”)
. Obecně to bude volání nějaké metody nebo získání dat. Obsah zadáváme obyčejným řetězcem a na to, abychom dostali odpověď, používáme completionHandler
, který má parametry objekt a error. Objekt má nastavenou hodnotu v případě úspěchu a error v případě chyby. Pokud ale voláte JS funkci, která nevrací nic, přijde vám objekt jako nil, tedy i v případě úspěchu může přijít prázdný objekt, i když chyba nenastala. A jak teda poznáme, že náš příkaz proběhl v pořádku, i když nic nevrací? Můžeme naslouchat JS messageHandlers a zpracovávat zprávy.
React ⏩️ Native
Tady je to trochu matoucí, protože jak na naší, tak i na React straně existuje messageHandler
.
- React – definuje messageHandler pro posílání zpráv, který má identifikační název. Může na něm volat funkci
postMessage
, čímž pošle zprávu klientovi a my tak získáme “komunikační most” ze strany Reactu. - V nativní aplikaci, abychom ten most přijali, musíme přidat do konfigurace
userContentController
most se stejným názvem a definovat, jak se bude chovat na zprávy, které zmessageHandleru
dorazí.
Pro každý messageHandler
tedy můžeme mít vlastní způsob zpracování v nativní appce. Je to skvělé hlavně kvůli tomu, že zprávy chodí pořád jako JSON formátované řetězce a můžeme je tak parsovat snadno pomocí systémových knihoven. Různé mosty nám pomáhají správně dekódovat zprávu. Tady bych zdůraznil, že se dá využít i ‘native-object-communication’. Název nám napovídá, že je komunikace nějakým způsobem nativní, ale musí se provádět pomocí Objective-C. S ohledem na to, jak málo iOS developerů se aktuálně vyzná v Objective-C a malému počtu typu zpráv potřebných v aplikaci, rozhodli jsme se použít systémové knihovny a nezanášet do projektu další závislost.
Obousměrná komunikace s React aplikací pomoci WebKitu je vlastně docela jednoduchá. Jak se ještě liší vývoj takové aplikace oproti standardní? Naše nativní appka má minimální zodpovědnost. Ideální je co nejvíce věcí řešit na straně React aplikace. Nativní appka pak slouží jako omezený prohlížeč, který nabízí mnohem více způsobů, jak využít potenciál telefonu a přidat webové aplikaci možnosti, o jakých se jí ani nesnilo.