Sjónarhorn iOS-forritara á uppþembd kóðagrunna, legacy-gildrur og 20 MB prófið.
Ég hef verið iOS-forritari síðan 2008, með áherslu á streymi og hlaðvörp. Ég byrjaði að vinna með HLS á iPhone árið 2009, og í gegnum árin hef ég byggt, viðhaldið, villuleitað og stundum erft streymisforrit af öllum stærðum.
Og ég hef myndað frekar sterka skoðun á því hvað „clean code" þýðir í raun og veru í þessari atvinnugrein. Ekki kennslubókarútgáfuna. Þá raunverulegu. Þá sem maður uppgötvar þegar maður opnar Xcode-verkefni einhvers annars og fyrsta eðlishvöt manns er að loka lokinu.
Ég hef farið yfir hundruð atvinnuauglýsinga og sjálfstæðra verktakasamninga fyrir iOS-forritara í gegnum árin. Næstum sérhver einasta auglýsing listar stoltlega „clean code" og „best practices" sem kröfur. SOLID-meginreglur. MVVM. Unit test-þekju. Hönnunarmynstur. Allan pakkann.
Og svo opnar maður verkefnið.
Bilið á milli atvinnuauglýsinga og raunveruleikans
Hér er það sem ég hef í raun og veru fundið þegar ég opnaði þessi „clean code" streymisverkefni: XIB-skrár frá 2014 sem enn keyra mikilvæg UI-flæði. Objective-C bridging headers sem eru lengri en sum heil forrit. Þrjú mismunandi netlag sem samvist hvert öðru vegna þess að enginn þorði að fjarlægja það gamla. Coordinator-mynstur stafla ofan á Navigator-mynstur stafla ofan á Router-mynstur, vegna þess að hver nýr aðalarkítekt bætti við sínu uppáhaldsmynstri án þess að fjarlægja það fyrra.
„Clean code" í flestum atvinnuauglýsingum fyrir streymisforrit er óskaþanki, ekki lýsing. Það lýsir því sem ráðningarstjórinn óskar að kóðagrunnurinn liti út eins og, ekki því sem bíður þín í gagnageymslunni.
Hér er raunveruleikaprófið sem enginn skrifar í starfslýsinguna: þetta Coordinator-mynstur sem þeir eru svona stoltir af? Það samhæfir þrjú önnur leiðsagnarmynstur sem enginn hafði tíma til að fjarlægja. Þessar SOLID-meginreglur? Þær leystust upp á því augnabliki sem forstjórinn vildi fá eiginleika sendann fyrir föstudag. Unit-prófin? Þau ná yfir innskráningarskjáinn og nákvæmlega ekkert annað.
Ég kasta ekki steinum úr glerhúsi. Ég hef sjálfur stuðlað að slíkri óreiðu. Sérhver farsímaforritari hefur gert það. En ég held að streymisiðnaðurinn hafi sérstaklega slæma útgáfu af þessu vandamáli, og ég hef kenningu um hvernig hægt er að koma auga á það samstundis.
20 MB reglan: lakmusprófið fyrir kóðagæði í streymisforritum
Hugsaðu um hvað streymisforrit gerir í raun og veru. Það sækir manifesto (HLS-spilunarlista, DASH MPD), matar hlutum í myndspilara, teiknar eitthvað notendaviðmót utan um það (rásir, EPG, stillingar), og það er nokkurn veginn þetta. Efnið er streymað. Þungu hlutirnir – myndbandið, hljóðið, smámyndirnar – búa allt á CDN, ekki í binary forritsins þíns.
Svo hér er kenning mín: ef streymisforrit vegur meira en 20 MB í App Store, þá er líklega sérhver megabæti umfram þann þröskuld „óhrein" kóði. Ekki illgjarn, ekki endilega gallasöm, heldur kóði sem ætti ekki að vera þar. Kóði sem endurspeglar lélegar arkitektúrákvarðanir sem hafa safnast upp í gegnum ár af málamiðlunum.
Skoðum nokkrar tölur. Nýjasta forritið mitt, My TV Channel, vegur 9 MB í App Store. Níu. Það keyrir staðbundið á iPhone, iPad, Mac (Apple Silicon), Apple TV og Apple Vision Pro. Það styður 9 tungumál. Notendur geta búið til og horft á línulegar sjónvarpsrásir allan sólarhringinn, með VOD-to-Live tímasetningu, push-tilkynningum, niðurhali án nets, mynd-í-mynd, fjölskjá, háþróaðri leit með raddinnslætti, eingöngu-hljóðstillingu, einkarásum og fullu efnisstjórnunarkerfi fyrir efnishöfunda. Þetta eru fleiri eiginleikar en mörg almennu streymisforritin.
Kíktu sjálfur á App Store. Flest stór streymisforrit vega á milli 80 og 200 MB. Sum fara enn hærra. Það er 10 til 20 sinnum þyngra en My TV Channel. Þessi forrit hafa sama aðalverkefni: streyma myndskeið. Samt bera þau jafngildi tugum My TV Channels í binary-skrám sínum.
Auðvitað þurfa stórar streymisþjónustur á einhverri af þeirri aukaþyngd að halda. Þær styðja breiðar tækjamatrísur, aðgengiseiginleika, DRM án nets, stundum leiki. En 150+ MB fyrir það sem er í grunninn myndbandstreymiforrit? Sú mismunur segir sögu um legacy-kóða, þvervettvangsmálamiðlanir og ára uppsafnaðar arkitektúrskuldir.
Hvaðan þenslan kemur
Eftir margra ára ráðgjöf á streymisverkefnum sé ég sömu mynstrin þenja binary-skrár forritsins langt umfram það sem nauðsynlegt er aftur og aftur.
Úrelt UI-tækni. XIB- og Storyboard-skrár eru sígild dæmi. Þær voru staðlað leiðin til að smíða iOS-viðmót í mörg ár, og þær fella inn raðaða hlutaneta, útlitsskorður, stundum jafnvel myndaleiðbeiningar beint í binary. Mörg streymisforrit bera enn XIB-skrár frá upprunalegri útgáfu, plástraðar og viðhaldnar en aldrei fluttar yfir á SwiftUI eða jafnvel nútíma UIKit-mynstur. Sérhver XIB-skrá er frosin tækniskuld með .xib-endingu.
Umkostnaður þvervettvangsvirkja. React Native, Flutter, Kotlin Multiplatform: hvert um sig bætir við sinni eigin keyrsluumhverfi, sínu eigin brúarlag, sínum eigin útdráttum. Fyrir streymisforrit þar sem afkastamikilvægasti hlutinn er staðbundni myndspilarinn hvort sem er, borgar málamiðlunin á milli þvervettvangshagræðis og binary-stærðar sjaldan sig. Maður endar á að senda JavaScript-vél (eða Dart VM, eða KMP-keyrsluumhverfi) bara til að birta rist af smámyndum sem SwiftUI eða UIKit meðhöndlar á broti af stærðinni.
Þetta er sama rökfræðin og leiddi bakendateymi niður í örtjónustukanínuholuna. Manstu þegar sérhvert sprotafyrirtæki þurfti Kubernetes og 47 Docker-gáma til að þjóna REST API sem eitt Django-forrit gat séð um? Farsímajafngildið er að senda þrjár virkjarekstrarumhverfi til að birta lista af myndböndum. Mynstrið er eins: að tileinka sér arkitektúrflækjustig sem leysir vandamál sem þú hefur ekki, á kostnaði sem þú greiðir í áratugi.
Uppsöfnun hönnunarmynstra. Þetta er lúmskara. Það birtist ekki beint sem megabæti, en það margfaldar skrár, flokka og útdrætti, sem eykur þýðingartímaháðleika, innfellda lýsigögn og binary-stærð. Ég hef séð streymisverkefni með sérstakt ViewModel, Coordinator, UseCase, Repository, DataSource, Mapper og Entity fyrir hvern einasta skjá. Það eru sjö skrár þar sem tvær myndu duga. Margfaldaðu með 30 skjáum og þú hefur 210 skrár í staðinn fyrir 60, þar sem hver ein bætir við flokkslýsigögnum í binary.
VIPER er versti brotamaðurinn hér. Það var hannað fyrir UIKit-heim þar sem gífurlega stórir view controllers voru raunverulegt vandamál. Að flytja VIPER inn í SwiftUI-verkefni er eins og að koma með slökkvibifreið að kerti. SwiftUI-sýnir eru nú þegar léttar, ástandslausar og samsetjanlegar af hönnun. Að vefja hverri einni inn í VIPER-stafla (View, Interactor, Presenter, Entity, Router) bætir við fimm skrám og þremur lögum af óbeinum tilvísunum fyrir eitthvað sem SwiftUI meðhöndlar með struct og @Observable flokki. Ég hef séð teymi gera þetta samt vegna þess að „þetta er arkitektúran okkar," og útkoman er alltaf sú sama: meiri boilerplate en viðskiptarökfræði.
Innfelldar auðlindir sem ættu að vera fjartengt. Innbyggð leturgerðir, innbyggðar hreyfimyndir (Lottie JSON-skrár eru alræmdar fyrir þetta), innbyggðar staðgengilsmyndir í 3x-upplausn fyrir hvern tækjaflokk. Í streymisforriti gæti nánast sérhver sjónræn auðlind verið sótt eftir þörfum frá CDN. Að innbyggja þau er lata leiðin, og það sýnir sig á umfanginu.
Dauður kóði frá yfirgefnum eiginleikum. A/B-prófunarvirkjar skilja eftir skilyrði sem aldrei verða hreinsuð upp. Misheppnuð eiginleikatilraunir verða áfram í kóðagrunninum vegna þess að „við förum kannski aftur í það." Greiningarsíðuþróunarsettið frá tveimur birgjum síðan er enn þýtt vegna þess að einhver gleymdi að fjarlægja það úr Podfile.
Raunverulegur kostnaður: þegar óhreinn kóði ákvarðar vegvísinn þinn
Binary-þensla er eitt. En versta afleiðing óhreins kóðagrunns er ekki niðurhalsstærðin. Það er hvað gerist á hverju sprints-skipulagsfundi.
Þú þekkir setninguna. Vörustjóri biður um nýjan eiginleika – segjum mynd-í-mynd, eingöngu-hljóðstillingu, einfalda UI-uppfærslu – og fyrstu orðin úr munni yfirforritarans eru: „Þetta verður flókið."
Þessi setning er lyktarprófið fyrir óhreinan kóða. Ekki „þetta tekur tíma," ekki „við þurfum að hugsa um jaðartilvik," heldur flókið. Kóðagrunnurinn er orðinn svo samofinn að enginn getur spáð fyrir um hvað það muni brjóta í þremur öðrum einingum ef maður snertir eina.
Í hreinum kóðagrunnum finnst eðlilegt að bæta við eiginleikum. Maður finnur rétta lagið, framlengir það, sendir. Í óhreinum kóðagrunnum finnst þetta eins og aðgerð á sjúklingi án sjúkraskrár. Sérhver breyting krefst fornleifafræðilegrar rannsóknar fyrst. Sérhvert mat kemur með áhættuþátt sem enginn þorir að setja á blað. Sérhvert sprint ber hið óyrtaða fyrirvara: „að því gefnu að ekkert óvænt bili."
Ég hef séð streymisverkefni þar sem innleiðing á einföldum „halda áfram að horfa" eiginleika krafðist breytinga á sjö arkitektúrlögum, tveimur bridging headers og sérsniðnum event bus sem enginn skildi alveg lengur. Þetta er ekki hugbúnaðarverkfræði. Þetta er gíslatökuviðræður við eigin kóðagrunn.
Og sá hluti sem vöruteymi skilja sjaldan: óhreinn kóði hægir ekki bara á þér í dag. Hann ákvarðar hvað þú getur byggt á morgun. Eiginleikum er ekki hafnað vegna þess að þeir séu slæmar hugmyndir. Þeim er hafnað vegna þess að „arkitektúran okkar styður það ekki," sem er kurteis leið til að segja „við byggðum okkur inn í horn fyrir fimm árum og enginn vill viðurkenna það." Kóðagrunnurinn verður de facto vörustjórinn, sem leggur neitunarvald við eiginleikum eingöngu með núningi.
Raunveruleikaprófun: keppinautar þínir með hreinni kóðagrunna munu senda sama eiginleikann á tveimur vikum á meðan teymið þitt er enn að kortleggja háðleikanet í Miro. Þeir eru ekki klárari. Þeir þurfa bara ekki að berjast við eigin kóðann áður en þeir berjast við markaðinn.
LLM-prófið: ný leið til að mæla hreinleika kóða
Fyrir utan binary-stærð er annað lakmusprófið sem ég hef notað undanfarið – eitt sem var ekki til fyrir fimm árum.
Beindu LLM að kóðagrunninum þínum. Ef það getur ekki skilið hann, getur næsta ráðningin þín það heldur ekki.
Verkfæri eins og Claude Code, OpenAI Codex og önnur AI-studd þróunarumhverfi eru mjög góð í að vafra um vel uppbyggða kóðagrunna. Þau geta lesið hreint Swift-verkefni, skilið arkitektúr þess, greint villur, lagt til lagfæringar og innleitt nýja eiginleika með lágmarks leiðsögn.
En reyndu að beina þeim að legacy streymisforriti með 15 ára uppsöfnuð mynstur, blandað Objective-C og Swift, þrjár mismunandi dependency injection nálganir og byggingakerfi haldið saman af sérsniðnum skeljaforskriftum. LLM mun eiga í erfiðleikum. Það mun ofskynja tengsl milli flokka sem eru ekki til. Það mun leggja til lagfæringar sem brjóta aðra hluta kerfisins. Það mun valda fleiri hrunum en reynslumikill forritari myndi.
Þetta er ekki takmörkun gervigreindar. Þetta er spegill. Ef LLM þjálfað á milljónum gagnageymsla getur ekki þáttað arkitektúr verkefnisins þíns þýðir það að útdrættir þínir leka, nafngiftir þínar eru ósamræmdar, háðleikar þínir eru flækjulegir og verkefnisuppbygging þín fylgir engum þekkjanlegu viðmiði.
Hugsaðu um þetta sem hið fullkomna „nýliðaþjálfunarpróf." LLM nálgast kóðagrunninn þinn með engan stofnanafræðslegan bakgrunn, aðeins mynsturgreiningu og víðtækan skilning á forritunarhefðum. Ef það villist, mun næsti ungforritari þinn líka villast. Og næsti reyndur forritari þinn mun eyða fyrstu þremur mánuðunum í að leysa sömu hnúta – nema hann mun reikningsfæra þig fyrir það.
Snúðu þessu nú við. Þegar kóðagrunnurinn þinn er hreinn gerist eitthvað áhugavert: verkfæri eins og Claude Code fara ekki bara yfir kóðann þinn, þau byggja með þér. Ég hef notað Claude Code á My TV Channel, og í hreinum kóðagrunni getur það innleitt nýjan eiginleika, skrifað prófin og opnað PR á þeim tíma sem það tók mig áður að skrifa Jira-miða. Það les arkitektúrinn, skilur hefðirnar og framleiðir kóða sem passar inn.
Þetta er þar sem hlutirnir verða áhugaverðir fyrir teymi sem enn keyra tveggja vikna sprints. Sprints voru hönnuð til að stjórna mannlegri óvissu: hversu langan tíma tekur þetta, hvað getum við skuldbundið okkur til, hvenær sýnum við. En þegar AI-umboðsmaður getur á áreiðanlegan hátt vafrað um kóðagrunninn þinn og sent virkan kóða á klukkustundum, verður sprintið sjálft flöskuhálsinn. Skipulagsfundurinn tekur lengri tíma en innleiðingin. Formálahátturinn í kringum mat á eiginleika kostar meiri tíma en að byggja hann.
Auðvitað virkar þetta bara ef kóðagrunnurinn er hreinn. Beindu Claude Code að VIPER-smituðu, XIB-hlaðnu, fjölvirkja-skrímsli og það er aftur komið í ofskynjanir. Verkfærið skapar ekki hraðann. Hreina arkitektúran gerir það. Claude Code afhjúpar hann bara. Og óhreinir kóðagrunnar? Þeir hægja ekki bara á mannlegum forritörum þínum lengur. Þeir hindra líka gervigreind frá því að hjálpa þér – og það verður sífellt dýrara hömlutap.
Hvernig clean code lítur í raun út í streymisforriti
Ég byggði My TV Channel frá grunni með þessar meginreglur í huga. Hér er hvað ég tel clean code þýða sérstaklega fyrir streymisforrit.
Fylgdu vettvangsviðmiðum. Human Interface Guidelines frá Apple eru til af ástæðu. Staðlaðir UIKit- eða SwiftUI-íhlutir gefa þér aðgengi, Dynamic Type, Dark Mode og staðfærslu ókeypis. Sérhver sérsniðinn íhlutur sem þú byggir í staðinn er einn sem þú þarft að viðhalda, prófa á milli tækja og villuleita þegar Apple breytir einhverju í nýrri iOS-útgáfu. My TV Channel keyrir á fimm Apple-vettvangi með sameiginlegum kóðagrunni vegna þess að það styðst við vettvangsinnfædda viðmótsupplifun – ekki vegna einhvers snjalls útdráttarlags.
Haltu háðleikanetinu grunnu. Streymisforrit þarf myndspilara, netlag og viðvarandi geymslulag. Umfram það ætti sérhver þriðja aðila háðleiki að vera vandlega yfirfarinn. Ekki allir háðleikar eru slæmir. Ég nota Kingfisher fyrir myndaflýtiminni í My TV Channel vegna þess að það gerir eitt vel, er virkt viðhaldið og binary-fótsporið er sanngjarnt miðað við gildið sem það veitir. Það er viðmiðið. Leysir háðleikinn raunverulegt vandamál betur en þú gætir með vettvangs-API? Er hann viðhaldinn? Er stærðin í hlutfalli við gildið? Ef svarið við einhverju af þessu er nei, á hann ekki heima í Podfile þínu. Vandamálið er ekki að nota forritasöfn. Vandamálið er að nota fimm þegar eitt myndi duga, eða nota 5 MB viðbragðsvirkja þegar innfæddur async/await og Combine í Swift sinna sama verkefni með engum ytri kóða.
Meðhöndlaðu binary-stærð sem eiginleika, ekki mæligildi. Notendur á farsímanetum, notendur með 64 GB iPhone-síma, notendur á mörkuðum þar sem geymslupláss er af skornum skammti: þeir njóta allir góðs af minni forriti. Apple sýnir forritsstærð áberandi í App Store af ástæðu. 9 MB niðurhal setur sig upp á sekúndum yfir hvaða tengingu sem er. 150 MB niðurhal krefst Wi-Fi fyrir marga notendur og keppir um pláss við myndir, skilaboð og önnur forrit sem þeir hugsa meira um.
Eyddu kóða. Erfiðasti hluti þess að viðhalda hreinum kóðagrunni er ekki að skrifa nýjan kóða. Það er að eyða gömlum kóða. Eiginleikaflagg sem hafa ekki verið rofin í sex mánuði, greiningaratburðir sem enginn athugar á mælaborðinu, flutningsleiðir fyrir gagnasniðmát frá þremur útgáfum síðan. Öllu þessu þarf að henda. Besti kóðinn er kóðinn sem er ekki til.
Áskorun til iðnaðarins
Streymi er einn samkeppnishæfasti flokkurinn í App Store. Samt senda flest OTT-forrit binary-skrár sem eru 5 til 20 sinnum stærri en þær þurfa að vera, bera árum saman af legacy-kóða og fylgja arkitektúrmynstrum sem jafnvel gervigreind getur ekki leyst úr.
Næst þegar þú sérð atvinnuauglýsingu fyrir iOS-forritara hjá streymisfyrirtæki sem krefst „clean code vinnubragða" og „nútíma arkitektúrs," spurðu eina spurningu: hversu stór er binary forritsins ykkar?
Ef svarið er norður af 50 MB fyrir eitthvað sem er í grunninn myndspilari með efnisskrá, þá veistu nákvæmlega hvað bíður þín í þeirri gagnageymslu.
Og ef þú vilt sjá hvernig streymisforrit lítur út þegar það er byggt frá grunni með clean code meginreglum – ekkert legacy, engar þvervettvangsmálamiðlanir, engar uppsafnaðar skuldir: sæktu My TV Channel og athugaðu stærðina sjálfur.
9 MB. Fimm vettvangar. Fullur af eiginleikum. Svona lítur clean code út.