Tidligere I år introduserte Vi React Native for iOS. React Native bringer det utviklere er vant til fra React on the web-deklarative selvstendige UI-komponenter og raske utviklingssykluser — til den mobile plattformen, samtidig som hastigheten, gjengivelsen og følelsen av innfødte applikasjoner beholdes. I Dag er Vi glade For å frigjøre React Native For Android.
På Facebook har Vi brukt React Native i produksjon i over et år nå. For nesten nøyaktig ett år siden bestemte teamet vårt seg for å utvikle Annonseadministrasjon-appen. Målet vårt var å lage en ny app for å la millioner Av mennesker som annonserer På Facebook administrere kontoene sine og opprette nye annonser på farten. Det endte opp med Å være Ikke Bare Facebook første Fullt Reagere Native app, men også den første cross-platform en. I dette innlegget vil vi gjerne dele med deg hvordan Vi bygget denne appen, Hvordan React Native gjorde det mulig for oss å bevege oss raskere, og leksjonene vi lærte.
Ved Å Velge React Native
For Ikke lenge siden Var React Native fortsatt en ny teknologi som ikke hadde blitt bevist i produksjonen. Mens utvikle en ny app basert på denne teknologien gjennomført noen risiko, det ble oppveies av de potensielle oppsider.
Først var vårt første team av tre produktingeniører allerede kjent Med React. For det andre måtte appen inneholde mye kompleks forretningslogikk for å håndtere forskjeller i annonseformater, tidssoner, datoformater, valutaer, valutakonvensjoner og så videre. Mye av Dette var allerede skrevet I JavaScript. Utsiktene til å skrive all den koden i Objective-C bare for å senere skrive den i Java for Android-versjonen av appen var ikke tiltalende-det ville heller ikke være effektivt. For Det tredje, I React Native ville det være enkelt å implementere de fleste GRENSESNITTFLATENE vi ønsket å bygge-vise mye data i form av lister, tabeller eller grafer. Produktingeniører kunne umiddelbart være produktive å implementere disse synspunktene, så lenge De visste React.
selvfølgelig presenterte noen funksjoner en utfordring for denne nye plattformen — for eksempel bildeditoren, som lar annonsører zoome og beskjære et bilde, og kartvisningen, som lar annonsører målrette folk innenfor en viss radius av et sted. Et annet eksempel er brødsmulenavigasjonen, som hjelper annonsører med å visualisere annonsehierarkiet i kontoene sine. Disse ga oss muligheter til å presse plattformen videre.
Bygge Annonser Manager for iOS første
vårt team besluttet å utvikle en iOS-versjon av programmet først, som justert svært godt Med React Native også utvikles først for iOS. Vi vokste teamet fra tre til åtte ingeniører i løpet av de følgende månedene. De nye rekruttene var ikke kjent Med React-og noen av Dem var ikke kjent Med JavaScript – men de var ivrige etter å bygge en god mobilopplevelse for våre annonsører, og de trappet opp raskt.
Erfarne iOS-ingeniører på React Native-teamet hjalp oss med å bygge bro over funksjoner som Ennå ikke var tilgjengelige I React Native, for eksempel å gi tilgang til telefonens kamerarull. De hjalp oss også med å pakke appen sammen med Noen Av Facebook ‘ s eksisterende iOS-biblioteker som allerede ble brukt i Andre Facebook-apper for å utføre autentisering, analyse, krasjrapportering, nettverk og push-varsler. Det lar vårt team fokusere på å bygge bare produktet.
som nevnt ovenfor kunne vi gjenbruke mange Av Våre Eksisterende JavaScript-biblioteker. Et slikt bibliotek Er Relay, Facebook rammeverk for å levere data Til React applikasjoner via GraphQL. Et annet sett med biblioteker behandlet internasjonalisering og lokalisering, noe som kan være vanskelig når tidssoner og valutaer er involvert. Normalt laster disse bibliotekene inn riktig konfigurasjon fra ET json-endepunkt på nettstedet. Vi skrev skript for å eksportere JSON-filene for alle støttede lokaliteter, inkluderte filene med appen ved hjelp av iOS lokaliserte bunter, og deretter utsatt JSON-dataene For JavaScript med noen få linjer med innfødt kode. Dette gjorde at bibliotekene våre kunne jobbe nesten uendret.
en av de største utfordringene vi møtte var navigasjonsflyten. For å navigere i en annonsørs eksisterende annonser og kampanjer, ønsket vi en brødsmulenavigeringslinje. For annonseopprettingsflyten trengte vi et navigasjonsfelt i veiviserstil. På toppen av det var det også viktig å få overgangsanimasjonene og berøringsbevegelsene riktig, ellers ville appen ha følt seg mer som et glorifisert mobilnettsted enn en innfødt app.
vår løsning var Navigator-komponenten, som ble gjort tilgjengelig sammen Med React Native under CustomComponents-katalogen. I hovedsak er Det En React-komponent som holder styr på et sett Med Andre React-komponenter i en stabel. Det kan vise en av disse komponentene og animere mellom dem basert på knappetrykk eller berøringsbevegelser. Den har også en pluggbar navigasjonslinjekomponent, som lar oss implementere en iOS – lignende navigasjonslinje for de fleste vanlige visninger, brødsmuler for å navigere i annonser og kampanjer, og en veiviserlignende stepper for opprettelsesflyten. Navigasjonslinjen komponent er varslet om animasjon fremgang og kan utføre den nødvendige animasjon inkrement å matche. Dette betyr at alle animasjoner, både for visningene og for navigasjonsfeltene, beregnes I JavaScript, men tester viste at vi fortsatt kunne utføre dem på 60 fps.
det er bare en måte at navigasjonsanimasjoner kan stamme, og det var Da JavaScript-tråden ble blokkert under en stor operasjon. Da vi møtte dette scenariet, var det nesten utelukkende på grunn av behandling av store mengder nylig hentet data. Selvfølgelig er det fornuftig at når du navigerer til en ny visning, må flere data lastes og behandles. På et tilstrekkelig raskt nettverk kan denne prosessen lett forstyrre en navigasjonsanimasjon som fortsatt pågår. Vår løsning her var å eksplisitt forsinke databehandlingen til animasjonene var ferdige, ved Hjelp Av InteractionManager-komponenten, som også leveres som En del Av React Native. Vi ville først animere til en visning som inneholdt plassholdere og deretter la Relay gjøre databehandlingen, som automatisk forårsaket de nødvendige React-komponentene å gjengi.
Sende En Android-versjon
Da Annonseadministrasjon for iOS var nær frakt, begynte vi å se på å bygge En Android-versjon av samme app. En React Native port Til Android virket som den beste måten å få det til å fungere. Heldigvis Var React Native-teamet allerede hardt på jobb og skapte nettopp det. Naturligvis ønsket vi å gjenbruke så mye appkode som mulig. Ikke bare forretningslogikken, men OGSÅ UI-koden, fordi de fleste visningene var stort sett de samme, lagre for litt styling. Selvfølgelig var Det steder Hvor Android-versjonen måtte se og føles forskjellig fra iOS-versjonen, for eksempel når Det gjelder navigasjon eller bruk av innfødte UI-elementer for datovelgere, brytere, etc.Heldigvis Hjalp React Native packagers blokkeringslistefunksjon og React ‘ s abstraksjonsmekanisme oss mye med å maksimere kodebruken på tvers av de to plattformene og minimere behovet for eksplisitte plattformkontroller. På iOS fortalte vi packager å ignorere alle filer som slutter .Android.js. For Android-utvikling ignorerte den alle filer som slutter på .ios.js. Nå kunne vi implementere samme komponent en Gang For Android og en gang for iOS, mens forbruker koden ville være uvitende om plattformen. Så i stedet for å introdusere eksplisitte if/else-sjekker for plattformen, prøvde vi å refactor plattformspesifikke deler av BRUKERGRENSESNITTET i separate komponenter som ville ha En android-og iOS-implementering. På tidspunktet for shipping Ads Manager for Android ga denne tilnærmingen rundt 85 prosent gjenbruk av appkode.
en større utfordring som vi møtte var hvordan å håndtere kildekoden. Android-og iOS-kodebaser ble administrert i To forskjellige arkiver På Facebook. Kildekoden For Ads Manager for iOS bodde i iOS-depotet, selvfølgelig, mens koden For Android-versjonen måtte leve I Android-depotet av ulike årsaker. For eksempel, mye som med iOS-versjonen, ønsket vi å gjøre bruk Av Noen Av Facebook ‘ S Android biblioteker, som bodde I Android depotet. I tillegg ble alle byggverktøyene, automatiseringen og kontinuerlig integrasjon for Android-apper koblet til Android-depotet. Gitt At Android-porten til appen krevde refactoring av eksisterende iOS-kode til abstrakte plattformspesifikke komponenter i egne filer, ville vi i hovedsak ha blitt stadig forking og sammenslåing av to versjoner av samme kodebase. Det virket som en uakseptabel situasjon for oss.
Til slutt bestemte vi oss for å utpeke iOS-depotet som sannhetskilden, for det meste fordi det allerede var der og iOS-versjonen av appen var den mest modne. Vi satte opp en cronjob som synkroniserte All JavaScript-kode fra iOS Til Android-depotet mange ganger om dagen. Å forplikte JavaScript Til Android-depotet ble motet og ble bare tillatt hvis det ble fulgt opp med en tilhørende forpliktelse til iOS-depotet. Hvis synkroniseringsskriptet oppdaget et avvik, arkiverte det en oppgave for videre undersøkelse.
Vi gjorde det også mulig For JavaScript packager-serveren å kjøre Android-kode fra iOS-depotet. På den måten kunne produktutviklerne våre, som for det meste berørte JavaScript og ingen innfødt kode, utvikle og teste endringene deres på både iOS og Android direkte fra iOS-depotet. Men det krevde fortsatt at De hadde bygget de innfødte delene Av Android-appen fra Android-depotet, og det samme for iOS-appen – en stor skatt når de testet endringer på to plattformer. For å øke hastigheten på flyten For JavaScript-bare utviklere, bygget vi også et skript som lastet ned riktig native binary fra våre kontinuerlige integrasjonsservere. Dette gjorde det unødvendig å til og med holde en klone Av Android-depotet for de fleste utviklere-de kunne gjøre All Sin JavaScript-utvikling fra sannhetskilden i iOS-depotet og iterere så fort som eller raskere enn På Facebook ‘ s webstack.
Hva vi lærte
React Native-teamet utviklet plattformen sammen med appen vår, og avslørte de innfødte komponentene og Apiene som vi trengte for å få det til å skje. Disse komponentene vil være til nytte for alle å bygge en app i fremtiden. Selv om vi måtte bygge ut noen komponenter selv, ville Det vært verdt Å Bruke React Native over pure native. Vi ville ha måttet skrive disse komponentene uansett, og de ville nok ikke vært gjenbrukbare av andre lag nedover veien.en leksjon vi lærte var at det å jobbe på tvers av separate iOS-og Android-kodelagre er vanskelig, selv med mange verktøy og automatisering. Da Vi bygde appen, Brukte Facebook denne modellen, og alle våre byggautomasjons-og utviklingsprosesser ble satt opp rundt den. Det fungerer imidlertid ikke bra for et produkt som for det meste har en enkelt delt JavaScript-kodebase. Heldigvis Flytter Facebook til et enhetlig lager for begge plattformene-bare en kopi av vanlig JavaScript-kode vil være nødvendig, og synkroniseringer vil være en ting fra fortiden.
En annen leksjon vi lærte om testing. Når du gjør endringer, må hver ingeniør være forsiktig med å teste på begge plattformer, og prosessen er utsatt for menneskelig feil. Men det er bare en uunngåelig konsekvens av å utvikle en plattformsapp fra samme kodebase. Når det er sagt, er kostnaden for en sporadisk uhell på grunn av utilstrekkelig testing langt oppveies av utviklingseffektiviteten oppnådd ved Å bruke React Native og å kunne gjenbruke kode på tvers av begge plattformene i utgangspunktet. Husk, denne leksjonen gjelder ikke bare for produktingeniører; det gjelder Også React Native platform engineers som arbeider I Objective-C og Java. Mye av arbeidet disse ingeniørene gjør er ikke bare begrenset til de respektive morsmål. Det kan også påvirke JavaScript — for eksempel komponent-Api-Er eller delvis delte implementeringer. Innfødte iOS-ingeniører er vanligvis ikke vant til å måtte teste endringer På Android, og omvendt gjelder Android-ingeniører. Dette er i hovedsak et kulturelt gap som tok tid og krefter på å lukke, og som et resultat, over tid, vår stabilitet har økt.
Vi løste også problemet ved å bygge integrasjonstester som ville kjøre på hver revisjon. Mens dette fungerte ut av boksen for å fange iOS-problemer på iOS og på Samme måte For Android, ble våre kontinuerlige integrasjonssystemer ikke satt opp For Å kjøre Android-tester på iOS-revisjoner og omvendt. Dette tok teknisk innsats for å løse, og det er fortsatt en stor nok feilmargin for å av og til bryte appen.Når Alt var sagt og gjort, betalte innsatsen vår — Vi kunne sende Facebook ‘ s første React Native-app på to plattformer, med innfødt utseende og følelse, bygget av samme Team Av JavaScript-ingeniører. Ikke alle ingeniørene var kjent Med React da de ble med i teamet, men de bygget en iOS-app med innfødt utseende og følelse på bare fem måneder. Og etter ytterligere tre måneder lanserte Vi Android-versjonen av appen.
I et forsøk på å være mer inkluderende i vårt språk, har vi redigert dette innlegget for å erstatte svarteliste med blokkeringsliste.