Sådan oprettes broer mellem rammer i en iOS-app

Hvis koden til din app ser sådan ud ...

"Jeg vil eksportere den del af min app, men den er bundet til resten af ​​appen som en spaghettiplade!"

Forsøger at eksportere en lille del af appen, som er for afhængig

Da jeg begyndte at modularisere en del af den app, jeg arbejdede på, løb jeg ind i en væg.

Jeg ønskede at eksportere en service (faktisk var det Tracking-tjenesten) i en separat ramme. Problemet var, at denne service var for næppe bundet til appen. Det brugte en anden tjeneste, der selv brugte en anden dybt forankret i appen.

For at eksportere sporingstjenesten ville jeg have været nødt til at refaktorere og omlægge hele servicen i de nye rammer!

Men faktum er, at jeg ikke havde tid til at gøre dette, og regressionstest ville have været et mareridt, og af mange andre grunde, som du kunne have i ethvert firma (proces, budget, frist).
Så jeg var nødt til at finde ud af, hvordan jeg eksporterer denne del af min app uden refactoring alt.

Lad os starte med et konkret eksempel!

Her er vi, den bedste måde at lære og forstå, hvordan tingene fungerer, er at øve! (Jeg vil give Github-repoen til dette eksempel i slutningen af ​​dette indlæg)
Så lad mig indstille konteksten, vi har en lille app med kun 2 skærme:

  • En hjemmeskærm
  • En betalingsskærm (vi vil eksportere den skærm til en ramme)

Betalingssiden indeholder en TextField til indtastning af et kortnummer og en betalingsknap. Når du trykker på knappen, skal betalingen startes.
Men ! Udfordringen ligger i betalingsmetoden. Lad os antage, at vi bare ikke kan eksportere betalingstjenesten af ​​nogle grunde, som jeg fremkaldte lidt tidligere.

Startskærm og betalingsskærm

Så vi har disse to skærme, der er erklæret i to forskellige mål. Startskærmen er deklareret i det primære appmål, og betalingsskærmen erklæres i et andet modul kaldet PaymentModule. Vi har også en PaymentService deklareret i det vigtigste appmål, som følger:

Betalingsmetoden er den metode, vi ikke kan udtrække fra appen, fordi den er for afhængig. Men vi vil bruge det fra betalingsmodulet.

Vi har en PaymentViewController defineret i betalingsmodulet, hvis vi prøver at ringe til PaymentService, har vi en fejl, da denne service ikke er i modulet. Du kan ikke importere hovedmålet inden for et modul (det ville være en vrøvl)

Så hvordan skal vi bruge denne metode fra PaymentViewController?

Definer en protokol i modulet

Dette bliver vores bro. Du skal definere en protokol i modulet med en metode, der beskriver, hvad du vil bruge i det primære appmål.

Så lad os definere en protokol, der hedder PaymentServiceProtocol med en metodeløn:

Implementering af protokollen i appen

Nu skal vi fortælle vores PaymentService at overholde denne protokol. Vi skal bare tilføje dette:

"Hvorfor den metode, der er angivet i protokollen, implementeres ikke i denne udvidelse?"

Du har ret, når du overholder en protokol, skal du implementere dens egenskaber og metoder. Tricket her er, at metodenavnet i protokollen er nøjagtigt det samme som metodenavnet i PaymentService, vi erklærede lidt tidligere. På den måde ved systemet, at det bliver nødt til at bruge den metodeløn, der er erklæret i klassen PaymentService, når der åbnes protokolmetoden.

Forbinder de to dele

Vi skal nu slutte de to dele sammen.
Fra HomeViewController starter vi en PaymentViewController, når vi trykker på knappen "Gå til betalingsside". På det tidspunkt overfører vi det til en henvisning til PaymentService-klassen, men betalingskontrolleren i modulet vil se det som en PaymentServiceProtocol-type.

Her er tricket:

Vi videregiver PaymentService.self, og koden i modulet ser en PaymentServiceProtocol.Type.
Nu kan vi bruge opkaldsbetalingsmetoden defineret i appen fra modulet!

Brug af broen

Det er nu meget let at bruge broen vi oprettede:

Metoden didTapPayButton kaldes, når du trykker på knappen Pay (lyder korrekt, ikke?). Kontroller på linje 23: vi kalder betalingsmetoden på den protokolreference, vi fik fra appen.

Da PaymentService er i overensstemmelse med denne protokol, udfører systemet koden inden for metoden, som er defineret i PaymentService.swift.

Med andre ord bruger vi den metode, som vi ikke kunne kalde fra modulet i starten! Broen er nu indstillet.

Sådan ser det ud, når du trykker på betalingsknappen.

Ved hjælp af betalingsmetoden indeholdt i hovedmålet fra betalingsmodulet

Konklusion

Afslutningsvis kan denne brodannelsesmetode bruges, hvis du vil eksportere en komponent af din app til en ramme.

Denne teknik giver dig mulighed for at skære nudlen ud af skålen, hvis du er tvunget til at eksportere den del af din app til en ramme, men du ikke kan eksportere det hele, uanset hvad du måtte have.

Jeg synes, dette er en midlertidig løsning, før du får ud hele komponenten inden for rammerne, når du f.eks. Har tid. (I dette scenario skal du en dag eksportere betalingsmetoden i betalingsmodulet)

Jeg indrømmer, at vi ikke ville gøre noget i den ideelle verden med enhjørninger og smarte ting. Vi vil hellere eksportere hele komponenten, men som sagt mange gange er dette ikke altid muligt.

Du kan finde Github-repo for dette projekt her, tøv ikke med at kontrollere, hvordan broen gøres, og prøve det selv.
Jeg håber, at dette indlæg kan hjælpe. Du er velkommen til at stille ethvert spørgsmål, du har i tankerne!

Denne historie er offentliggjort i The Startup, Medium's største iværksætterpublikation efterfulgt af +442.678 personer.

Abonner for at modtage vores tophistorier her.