Jak vytvořit mosty mezi rámci v aplikaci pro iOS

Pokud kód vaší aplikace vypadá takto:

"Chci exportovat tu část své aplikace, ale je spojena se zbytkem aplikace jako špagetová deska!"

Pokoušíme se exportovat malou část aplikace, která je příliš závislá

Když jsem začal modularizovat část aplikace, na které jsem pracoval, narazil jsem do zdi.

Chtěl jsem exportovat službu (ve skutečnosti to byla služba Tracking) do samostatného rámce. Problém byl v tom, že tato služba byla s aplikací příliš spojena. Využívala další službu, která sama o sobě používala další hluboce ukotvenou v aplikaci.

Abych mohl exportovat sledovací službu, musel bych refaktorovat a předělat celou sadu služeb v novém rámci!

Faktem však je, že jsem neměl čas na to a regresní testování by bylo noční můrou a z mnoha jiných důvodů, které byste mohli mít v jakékoli společnosti (proces, rozpočet, termín).
Musel jsem tedy zjistit, jak exportovat tuto část mé aplikace, aniž bych všechno refaktoroval.

Začněme konkrétním příkladem!

Zde jsme, nejlepší způsob, jak se učit a pochopit, jak věci fungují, je praktikovat! (Na konci tohoto příspěvku poskytnu repozitář Github pro tento příklad)
Dovolte mi tedy nastavit kontext, máme malou aplikaci s pouze 2 obrazovkami:

  • Domovská obrazovka
  • Obrazovka plateb (tuto obrazovku chceme exportovat do rámce)

Platební stránka obsahuje TextField pro zadání čísla karty a tlačítko Pay. Když stisknete tlačítko, platba by měla být zahájena.
Ale ! Úkol spočívá v platební metodě. Předpokládejme, že nemůžeme exportovat platební službu z nějakých důvodů, které jsem evokoval o něco dříve.

Domovská obrazovka a obrazovka plateb

Máme tedy tyto dvě obrazovky, deklarované ve dvou různých cílech. Domovská obrazovka je deklarována v hlavním cíli aplikace a obrazovka plateb je deklarována v jiném modulu nazvaném PaymentModule. V hlavním cíli aplikace je také deklarována služba PaymentService:

Způsob platby je metoda, kterou nemůžeme z aplikace získat, protože je příliš závislá. Chceme ji však použít z platebního modulu.

Máme modul PaymentViewController definovaný v modulu Payment, pokud se pokusíme zavolat PaymentService, dojde k chybě, protože tato služba není v modulu. V modulu nemůžete importovat hlavní cíl (to by byl nesmysl)

Jak tedy použijeme tuto metodu z nástroje PaymentViewController?

Definujte protokol v modulu

Tohle bude náš most. V modulu musíte definovat protokol pomocí metody popisující, co chcete použít v hlavním cíli aplikace.

Definujme tedy protokol s názvem PaymentServiceProtocol s metodou platby:

Implementace protokolu v aplikaci

Nyní musíme sdělit naší platební službě, aby vyhovovala tomuto protokolu. Stačí přidat toto:

"Proč metoda deklarovaná v protokolu není implementována v tomto rozšíření?"

Máte pravdu, když se přizpůsobujete protokolu, musíte implementovat jeho vlastnosti a metody. Trik je v tom, že název metody v protokolu je přesně stejný jako název metody v PaymentService, kterou jsme deklarovali o něco dříve. Tímto způsobem bude systém vědět, že při přístupu k metodě protokolu bude muset použít metodu placení deklarovanou ve třídě PaymentService.

Propojení obou částí

Nyní musíme spojit obě části dohromady.
Po klepnutí na tlačítko „Přejít na stránku platby“ z ovládacího prvku HomeViewController spustíme ovládací prvek PaymentViewController. V tuto chvíli ji předáme odkaz na třídu PaymentService, ale správce plateb v modulu ji bude považovat za typ PaymentServiceProtocol.

Zde je trik:

Předáváme PaymentService.self a kód v modulu zobrazuje PaymentServiceProtocol.Type.
Nyní můžeme použít volání metody platby definované v aplikaci z modulu!

Pomocí mostu

Nyní je velmi snadné použít most, který jsme vytvořili:

Metoda didTapPayButton je volána pokaždé, když klepnete na tlačítko Pay (zní správně, že?). Kontrola na řádku 23: voláme metodu platby na odkaz na protokol, který jsme dostali z aplikace.

Protože PaymentService vyhovuje tomuto protokolu, provede systém kód uvnitř metody pay, která je definována v PaymentService.swift.

Jinými slovy, používáme metodu, kterou jsme na začátku nemohli volat z modulu! Most je nyní nastaven.

Jak to vypadá, když klepnete na tlačítko platby.

Použití platební metody obsažené v hlavním cíli z platebního modulu

Závěr

Na závěr lze tuto přemosťovací metodu použít, pokud chcete exportovat součást aplikace do rámce.

Tato technika vám umožní vystřihnout nudle z misky, pokud jste nuceni exportovat tuto část aplikace do rámce, ale nemůžete exportovat celou věc, z jakéhokoli důvodu byste mohli mít.

Myslím si, že se jedná o dočasné řešení, než se dostaneme ven z celé komponenty uvnitř rámce, kdy budete mít například čas. (V tomto scénáři jednou budete muset exportovat způsob platby uvnitř platebního modulu)

Přiznávám, že v ideálním světě, s jednorožci a ozdobnými věcmi, bychom něco takového neudělali. Raději bychom exportovali celou složku, ale jak jsem mnohokrát řekl, není to vždy možné.

Githubův repo tohoto projektu najdete zde, neváhejte a podívejte se, jak se most dělá, a vyzkoušejte ho sami.
Doufám, že tento příspěvek může pomoci, neváhejte se zeptat na jakoukoli otázku, kterou máte na mysli!

Tento příběh je publikován v The Startup, střední největší podnikatelské publikaci média, po níž následuje +442 678 lidí.

Přihlaste se k odběru a získejte zde naše nejlepší příběhy.