React Native for Android: miten rakensimme ensimmäisen cross-platform React Native app – Facebook Engineering

aiemmin tänä vuonna otimme React Native for iOS: n käyttöön. React Native tuo sen, mihin kehittäjät ovat tottuneet React on the webistä — deklaratiiviset itsenäiset KÄYTTÖLIITTYMÄKOMPONENTIT ja nopeat kehityssyklit-mobiilialustalle säilyttäen samalla natiivisovellusten nopeuden, uskollisuuden ja tuntuman. Tänään julkaisemme React natiivin Androidille.

Facebookilla olemme käyttäneet React Native-tuotetta tuotannossa jo yli vuoden. Lähes tasan vuosi sitten tiimimme lähti kehittämään Ads Manager-sovellusta. Tavoitteenamme oli luoda uusi sovellus, jonka avulla miljoonat ihmiset, jotka mainostavat Facebook-sivuilla, voivat hallita tilejään ja luoda uusia mainoksia tien päällä. Se päätyi paitsi Facebook ensimmäinen täysin reagoi natiivi sovellus, mutta myös ensimmäinen cross-platform yksi. Tässä viestissä, haluamme kertoa teille, miten rakensimme tämän sovelluksen, Miten React Native mahdollisti meille liikkua nopeammin, ja opit opimme.

valitsemalla React Native

jokin aika sitten React Native oli vielä uusi tekniikka, jota ei ollut todistettu tuotannossa. Vaikka uuden sovelluksen kehittäminen perustuu tähän teknologiaan mukana joitakin riskejä, se oli suurempi kuin mahdolliset hyvät puolet.

aluksi kolmen tuoteinsinöörin alkutiimimme tunsi jo Reactin. Toiseksi, sovellus tarvitsi sisältää paljon monimutkaisia liiketoiminnan logiikka tarkasti käsitellä eroja mainosmuodot, aikavyöhykkeet, päivämäärä formaatteja, valuutat, valuutta yleissopimukset, ja niin edelleen. Suuri osa tästä kirjoitettiin jo Javascriptillä. Mahdollisuus kirjoittaa kaikki, että koodi Objective-C vain myöhemmin kirjoittaa sen Java Android-versio sovellus ei houkutteleva-eikä se olisi tehokas. Kolmanneksi React Native – versiossa olisi helppo toteuttaa suurin osa käyttöliittymän pinnoista, jotka halusimme rakentaa — näyttämällä paljon dataa luetteloiden, taulukoiden tai kaavioiden muodossa. Tuoteinsinöörit voisivat olla välittömästi tuottavia näiden näkemysten toteuttamisessa, kunhan he tietäisivät reagoida.

jotkin ominaisuudet olivat tietysti haaste tälle uudelle alustalle — esimerkiksi kuvankäsittelyohjelma, jonka avulla mainostajat voivat zoomata ja rajata kuvaa, ja karttanäkymä, jonka avulla mainostajat voivat kohdistaa kohteensa tiettyyn säteeseen sijoittuviin ihmisiin. Toinen esimerkki on leipäkrumbanavigointi, joka auttaa mainostajia visualisoimaan mainosten hierarkian tileillään. Nämä tarjosivat meille mahdollisuuksia viedä alustaa eteenpäin.

Building Ads Manager for iOS first

tiimimme päätti kehittää sovelluksesta ensin iOS-version, joka sopi hyvin yhteen React nativen kanssa, joka myös kehitettiin ensin iOS: lle. Kasvatimme tiimiä kolmesta kahdeksaan insinööriin seuraavien kuukausien aikana. Uudet tulokkaat eivät tunteneet Reactia — ja jotkut heistä eivät tunteneet JavaScriptiä — mutta he olivat innokkaita rakentamaan mainostajillemme loistavan mobiilikokemuksen, ja he räväyttivät nopeasti.

kokeneet React Native-tiimin iOS-insinöörit auttoivat meitä bridgeominaisuuksissa, joita ei vielä ollut React Native-versiossa, kuten tarjoamalla pääsyn puhelimen kamerarullaan. He auttoivat meitä myös niputtamaan sovelluksen joihinkin Facebookin olemassa oleviin iOS-kirjastoihin, joita käytettiin jo muissa Facebook-sovelluksissa todentamisen, analytiikan, kaatumisraportoinnin, Facebook-verkottumisen ja push-ilmoitusten suorittamiseen. Se antoi tiimimme keskittyä vain tuotteen rakentamiseen.

kuten edellä mainittiin, pystyimme käyttämään uudelleen paljon olemassa olevia JavaScript-kirjastojamme. Yksi tällainen kirjasto on Relay, Facebook ’ s framework for delivering data to React applications via GraphQL. Toinen joukko kirjastoja käsitteli kansainvälistymistä ja lokalisointia, mikä voi olla hankalaa, kun aikavyöhykkeet ja valuutat ovat mukana. Normaalisti nämä kirjastot lataavat oikean kokoonpanon JSON-päätepisteestä verkkosivustolla. Kirjoitimme skriptejä viedä JSON tiedostot kaikille tuetuille locales, mukana tiedostot sovelluksen avulla iOS: n lokalisoitu niput, ja sitten altistetaan JSON tiedot JavaScript muutaman rivin natiivi koodi. Tämä mahdollisti kirjastojemme toiminnan lähes muuttumattomana.

yksi suurimmista haasteista oli suunnistusvirrat. Mainostajan olemassa olevien mainosten ja kampanjoiden navigointiin halusimme leipäkrumb-navigointipalkin. Mainosten luontivirtaa varten tarvittiin velhotyylinen navigointipalkki. Päälle, että, se oli myös tärkeää saada siirtymäanimaatiot ja touch eleet oikein, muuten sovellus olisi tuntunut enemmän ylistetty mobiilisivusto kuin natiivi sovellus.

ratkaisumme oli Navigator-komponentti, joka tuli React nativen kanssa saataville CustomComponents-hakemistossa. Pohjimmiltaan se on Reaktiokomponentti, joka pitää kirjaa muista Reaktiokomponenteista pinossa. Se voi näyttää yhden näistä komponenteista ja animoida niiden välillä perustuen napinpainalluksiin tai kosketuseleisiin. Siinä on myös kytkettävä navigointipalkkikomponentti, jonka avulla voimme toteuttaa iOS: n kaltaisen navigointipalkin useimpia säännöllisiä näkymiä varten, leivänmuruja mainosten ja kampanjoiden navigointiin sekä ohjatun stepperin luomisvirtaa varten. Navigointipalkin osalle ilmoitetaan animaation edistymisestä ja se voi suorittaa tarvittavan animaation lisäyksen. Tämä tarkoittaa, että kaikki animaatiot, sekä näkymien että navigointipalkkien osalta, on laskettu Javascriptillä, mutta testit osoittivat, että pystyimme silti suorittamaan ne 60 fps: n nopeudella.

on vain yksi tapa, jolla navigointianimaatiot voivat änkyttää, ja se on, kun JavaScript-säie estettiin ison operaation aikana. Kun kohtasimme tämän skenaarion, se johtui lähes yksinomaan suurten uusien tietojen käsittelystä. On tietenkin järkevää, että kun navigoit uuteen näkymään, lisää dataa pitää ladata ja käsitellä. Riittävän nopeassa verkossa tämä prosessi voisi helposti häiritä vielä käynnissä olevaa navigointianimaatiota. Ratkaisumme tässä oli nimenomaan viivyttää tietojenkäsittelyä, kunnes animaatiot ovat valmiita, käyttäen InteractionManager-komponenttia, joka myös toimitetaan osana React Native-ohjelmaa. Ensin animoimme näkymän, joka sisälsi paikkamerkit, ja sitten annoimme releen tehdä tietojenkäsittelyn, mikä aiheutti automaattisesti tarvittavien Reagointikomponenttien uudelleenrenderöinnin.

Android-version toimittaminen

kun iOS: n Ads Manager oli lähellä toimitusta, aloimme miettiä Android-version rakentamista samasta sovelluksesta. React natiivi portti Android tuntui paras tapa saada se toimimaan. Onneksi React natiivi joukkue oli jo kovaa työtä luoda juuri sitä. Halusimme luonnollisesti uusiokäyttää mahdollisimman paljon sovelluskoodia. Ei vain liiketoiminnan logiikka, mutta myös UI koodi, koska useimmat näkymät olivat pitkälti samat, lukuun ottamatta joitakin muotoilu. Tietenkin, oli paikkoja, joissa Android-versio piti näyttää ja tuntuu erilaiselta kuin iOS-versio, esimerkiksi kannalta navigointi tai käyttämällä natiivi UI elementtejä päivämäärä poimijat, kytkimet, jne.

onneksi React Native packager ’s block list-ominaisuus ja React’ s abstraction-mekanismi auttoivat meitä paljon maksimoimalla koodin uudelleenkäytön kahdella alustalla ja minimoimalla eksplisiittisten alustatarkistusten tarpeen. IOS: ssä käskimme pakkaajaa jättämään huomiotta kaikki tiedostot, jotka päättyvät .androidi.js. Android kehitys, se jätti huomiotta kaikki tiedostot päättyy .ios.js. Nyt voisimme toteuttaa saman komponentin kerran Androidille ja kerran iOS: lle, kun taas kuluttava koodi olisi tietämätön alustalle. Joten sen sijaan, että olisimme ottaneet käyttöön nimenomaisia if / else-tarkistuksia alustalle, yritimme muokata käyttöliittymän alustakohtaisia osia erillisiksi komponenteiksi, joilla olisi Android-ja iOS-toteutus. Tuolloin merenkulun Ads Manager Android, että lähestymistapa tuotti noin 85 prosenttia uudelleenkäyttöä sovelluksen koodin.

suurempi haaste oli, miten lähdekoodia hallitaan. Android-ja iOS-koodebaaseja hallittiin kahdessa eri arkistossa Facebookilla. IOS: n Ads managerin lähdekoodi asui tietenkin iOS-arkistossa, kun taas Android-version koodin olisi elettävä Android-arkistossa eri syistä. Esimerkiksi, aivan kuten iOS-versio, halusimme hyödyntää muutamia Facebook Android Kirjastot, joka asui Android arkistossa. Lisäksi kaikki Android-sovellusten rakentamistyökalut, automaatio ja jatkuva integraatio kytkettiin Android-arkistoon. Koska sovelluksen Android-portti edellytti olemassa olevan iOS-koodin uudelleenportointia alustakohtaisten komponenttien abstraktoimiseksi omiin tiedostoihinsa, olisimme käytännössä jatkuvasti haarukoineet ja yhdistäneet kaksi versiota samasta koodista. Se tuntui meistä mahdottomalta hyväksyä.

lopulta päätimme nimetä iOS-arkiston totuuden lähteeksi lähinnä siksi, että se oli jo olemassa ja sovelluksen iOS-versio oli kypsin. Perustimme cronjob, joka synkronoi kaikki JavaScript koodin iOS Android arkistoon monta kertaa päivässä. JavaScriptin toimittaminen Android-arkistoon ei ollut sallittua, ja se sallittiin vain, jos sitä seurattiin mukana toimituksella iOS-arkistoon. Jos sync script havaitsi poikkeaman, se jätti tehtävän jatkotutkimuksiin.

Mahdollistimme myös JavaScript-packager-palvelimen Android-koodin ajamisen iOS-arkistosta. Tällä tavoin tuotekehittäjämme, jotka koskivat enimmäkseen JavaScriptiä eikä natiivikoodia, voisivat kehittää ja testata muutoksiaan sekä iOS: llä että Androidilla suoraan iOS-arkistosta. Mutta se edellytti silti, että he ovat rakentaneet alkuperäiset osat Android-sovelluksen Android repository, ja sama iOS-sovellus-valtava vero, kun testaus muuttuu kahdella alustalla. Nopeuttaaksemme vain JavaScript-kehittäjien toimintaa rakensimme myös komentosarjan, joka latasi sopivan natiivibinaarin jatkuvan integraation palvelimiltamme. Tämä teki tarpeettomaksi edes pitää klooni Android arkisto useimmille kehittäjille-he voisivat tehdä kaikki JavaScript-kehitys lähteestä totuuden iOS arkistoon ja iteroida niin nopeasti tai nopeammin kuin Facebook web pino.

mitä opimme

React Native-tiimi kehitti Alustan sovelluksemme rinnalla ja paljasti native-komponentit ja sovellusliittymät, joita tarvitsimme sen toteuttamiseksi. Näistä komponenteista on hyötyä kaikille sovelluksen rakentajille tulevaisuudessa. Vaikka meidän olisi täytynyt rakentaa muutama komponentti itse, React Native olisi silti ollut sen arvoista. Meidän olisi pitänyt kirjoittaa ne osat Joka tapauksessa, ja ne eivät luultavasti olisi olleet uudelleenkäytettäviä muiden ryhmien tiellä.

yksi opetus meille oli, että työskentely erillisissä iOS-ja Android-koodivarastoissa on vaikeaa, vaikka käytössä on paljon työkaluja ja automaatiota. Kun rakensimme sovellusta, Facebook käytti tätä mallia, ja kaikki rakennusautomaatiomme ja kehittäjäprosessimme perustettiin sen ympärille. Kuitenkin, se ei toimi hyvin tuote, joka, suurimmaksi osaksi, on yksi jaettu JavaScript codebase. Onneksi, Facebook on siirtymässä yhtenäiseen arkistoon molemmille alustoille-vain yksi kopio yhteistä JavaScript-koodia tarvitaan, ja synkronointi on menneisyyteen.

toinen oppimamme läksy koski testausta. Muutoksia tehdessään jokaisen insinöörin on oltava huolellinen molempien alustojen testaamisessa, ja prosessi on altis inhimillisille virheille. Mutta se on vain väistämätön seuraus kehittää cross-platform-sovellus samasta koodebase. Se sanoi, kustannukset satunnaisen vahinko johtuu riittämättömästä testauksesta on paljon suurempi kuin kehitystehokkuus saatu käyttämällä React Native ja mahdollisuus käyttää koodia molemmilla alustoilla ensinnäkin. Muista, että tämä opetus ei koske vain tuoteinsinöörejä; se koskee myös React Native platform-insinöörejä, jotka työskentelevät Objective-C: ssä ja Javassa. Suuri osa näiden insinöörien tekemästä työstä ei rajoitu pelkästään kulloisiinkaan äidinkieliin. Se voi vaikuttaa myös Javascriptiin-esimerkiksi komponenttirajapintoihin tai osittain jaettuihin toteutuksiin. Natiivi iOS insinöörit eivät yleensä ole tottuneet ottaa testata muutoksia Android, ja päinvastainen on totta Android insinöörejä. Kyse on pääasiassa kulttuurisesta kuilusta, jonka kurominen umpeen vaati aikaa ja vaivaa, minkä seurauksena vakaudemme on ajan myötä kasvanut.

ongelmaan puututtiin myös rakentamalla integraatiotestejä, jotka suoritettaisiin jokaisessa uudistuksessa. Vaikka tämä toimi kättelyssä kiinni iOS kysymyksiä iOS ja samoin Android, meidän jatkuva integrointi järjestelmiä ei perustettu suorittaa Android testejä iOS versiot ja päinvastoin. Tämä vaati insinöörityötä ratkaista, ja siellä on vielä tarpeeksi suuri virhemarginaali ajoittain rikkoa sovelluksen.

kun kaikki oli sanottu ja tehty, vetomme kannatti — pystyimme lähettämään Facebookille ensimmäisen täysin React Native-sovelluksen kahdella alustalla, joissa oli native-ulkoasu, jonka rakensi sama JavaScript-insinöörien tiimi. Kaikki insinöörit eivät tunteneet Reactia liittyessään tiimiin, mutta he rakensivat iOS-sovelluksen, jossa oli natiivi ulkoasu vain viidessä kuukaudessa. Ja kun vielä kolme kuukautta, julkaisimme Android-version sovelluksen.

pyrkiessämme olemaan inklusiivisempia kielellämme, olemme muokanneet tätä viestiä korvataksemme mustan listan block list-listalla.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *