V júni 2023, keď spoločnosť Apple oznámila Vision Pro, som mal nápad, ktorý by mohol dobre fungovať na náhlavnej súprave – kolekcia videí v slučke, ktorá sa prehráva popri vašom každodennom používaní. Už som mal aplikáciu, ktorá to dokázala s názvom Christmas Chill , niečo, čo som vytvoril, keď bola sprístupnená prvá Apple TV podporujúca App Store. Obsahuje kolekciu zacyklených videí, ktoré môžete použiť ako slávnostné pozadie.
Každý rok cez zimu strávim niekoľko dní jeho vylepšovaním, pridávaním nového obsahu a zlepšovaním kódovej základne. Jedna z väčších zmien projektu prišla v decembri 2023, keď bolo používateľské rozhranie migrované z UIKit a Storyboards do SwiftUI.
No, väčšinou migroval. Potreboval som pohľad podporovaný AVPlayer zabalený do UIViewRepresentable . Skvelé API poskytujúce interoperabilitu medzi UIKit a SwiftUI, ak by ste to niekedy potrebovali.
Trochu som váhal s migráciou skôr, pretože som dobre porozumel deklaratívnemu používateľskému rozhraniu a jeho konceptom z inej práce s React a Jetpack Compose . To sa pre mňa zmenilo, keď Apple predstavil Apple Vision Pro a jeho podporu pre SwiftUI. Christmas Chill bol pekný projekt na udržanie mojich vedomostí o Apple Dev aktuálne a chcel som získať skúsenosti s rozšírením aplikácie na rôzne zariadenia.
Po dokončení migrácie na SwiftUI pre Christmas Chill v roku 2023 som sa v roku 2024 rozhodol pridať podporu pre Vision Pro. Nižšie je uvedené, ako som na to išiel a čo odporúčam, ak sa pokúšate urobiť to isté pre svoje vlastné aplikácie.
Na začiatok musí byť projekt schopný postaviť Vision Pro ako cieľ; urobiť to je prekvapivo jednoduché! Vo vnútri Xcode vyberte súbor .xcodeproj
a v rozbaľovacej ponuke Podporované destinácie kliknite na tlačidlo plus.
Zobrazí sa rozbaľovacia ponuka všetkých dostupných platforiem Apple. Umiestnite kurzor myši na požadovanú platformu, ktorú chcete pridať ako cieľ, v tomto prípade Apple Vision, a potom kliknite na Apple Vision v novo sa zobrazenej sekcii.
Zobrazí sa malé vyskakovacie okno, ktoré vás informuje o zmenách, ktoré Xcode musí vykonať v cieli. Kliknite na položku Povoliť .
Potom vytvorte aplikáciu pomocou simulátora visionOS. Ak máte po ruke Vision Pro, tu nájdete pokyny, ako ho nainštalovať do zariadenia.
Počas kompilácie je pravdepodobné, že Xcode nájde chyby kompilátora a/alebo aplikácia zlyhá. Toto sa očakáva a je to prax v trpezlivosti. Od tohto bodu musíte opraviť chyby vo svojom projekte, kým sa aplikácia neskompiluje a už nepadne.
V mojom prípade to trvalo asi 30 minút, čiastočne vďaka predchádzajúcej tvrdej práci na migrácii aplikácie z UIKit do SwiftUI!
SwiftUI je vo svojom jadre multiplatformový rámec, čo znamená, že iba kompiláciou kódu SwiftUI pre inú platformu zmení svoj vzhľad. Berúc do úvahy štýl platformy a rôzne spôsoby interakcie.
Aj keď to pomáha dosiahnuť rýchly pokrok počas vývoja, možno budete chcieť mať väčšiu kontrolu nad tým, ako aplikácia vyzerá, a využiť silné stránky jednotlivých platforiem. Dobrým príkladom sú schopnosti Vision Pro Immersion; SwiftUI na to poskytuje API cez ImmersiveSpace , API dostupné len pre visionOS.
Ak ste sa pokúsili použiť toto API pri kompilácii projektu pre Apple TV, Xcode zobrazí chybu informujúcu o tom, že toto API nie je dostupné.
Aké je teda riešenie, ako sa tejto situácii vyhnúť? Odpoveď pochádza z použitia blokov podmienenej kompilácie . Kompilačné bloky sú časti kódu, ktoré poskytujú pokyny, kedy má kompilátor kompilovať kód v rámci bloku.
Aj keď podporujú rôzne podmienky, najužitočnejšie pre naše potreby je zistenie, pre ktorú platformu sa kód kompiluje. Môžete to urobiť pomocou niekoľkých riadkov kódu:
var body: some Scene { #if os(tvOS) WindowGroup { HStack { Text("I am running on tvOS!") } } #elseif os(visionOS) ImmersiveSpace(id: "MyImmersiveSpace") { } #endif }
Príjemnou vlastnosťou Xcode na podporu blokov podmienenej kompilácie je objasnenie toho, aký kód sa bude kompilovať v závislosti od platformy vybranej na kompiláciu. Tiež mierne vybledne kód, ktorý nebude skompilovaný.
Jedným z užitočnejších trikov, ktoré som našiel, je použitie fáz zostavovania zdrojov kompilácie a kopírovania zdrojov balíka ako formy injekcie závislosti. Tieto procesy sa spúšťajú pri zostavovaní aplikácie a možno ich nájsť na karte Fázy zostavenia v projekte Xcode.
Compile Sources robí ťažkú prácu pri kompilácii vášho zdrojového kódu do strojového kódu. Či už je to Swift, Objective-C, alebo dokonca C/C++.
Copy Bundle Resources skopíruje všetky súvisiace zdroje pre cieľ aplikácie do App Bundle . Kontajner rôznych druhov pre všetok kód a zdroje aplikácie vrátane obrázkov, videí, lokalizovateľných reťazcov a ďalších.
Tieto dve fázy zostavovania poskytujú aplikáciám veľkú flexibilitu, pretože každý nový cieľ poskytuje svoje vlastné fázy zostavovania vrátane dvoch vyššie uvedených krokov. Túto techniku okrem iného využívajú aplikácie Whitelabel, ktoré firmám poskytujú spôsob, ako si prispôsobiť svoj obsah.
Možno zistíte, že chcete svojim vlastným aplikáciám poskytovať rôzny obsah v závislosti od platformy, na ktorej bežia. Využime tieto fázy budovania v náš prospech a poskytnime na to dva rôzne zdroje obsahu.
Najprv použiteprotokol Swift na poskytnutie zmluvy, ktorá očakáva, že bude splnená štruktúrou alebo triedou.
protocol ContentManager { var content: [Content] { get } }
Ďalej sa pozrime na dvoch implementátorov protokolu. Tu je prvý:
class TargetAppAContentManager : ContentManager { var content: [Content] { return [ Content(name: TargetAppAContentIdentifier.videoOneName.rawValue, image: TargetAppAImagePreviewIdentifier.videoOnePreview.rawValue, video: TargetAppAImageVideoIdentifier.videoOneVideo.rawValue), Content(name: TargetAppAContentIdentifier.videoTwoName.rawValue, image: TargetAppAImagePreviewIdentifier.videoTwoPreview.rawValue, video: TargetAppAImageVideoIdentifier.videoTwoVideo.rawValue), Content(name: TargetAppAContentIdentifier.videoThreeName.rawValue, image: TargetAppAImagePreviewIdentifier.videoThreePreview.rawValue, video: TargetAppAImageVideoIdentifier.videoThreeVideo.rawValue), ] return contentToShow } }
TargetAppAContentManager
je konkrétna implementácia použitá pre prvý cieľ aplikácie. Poskytuje pole Content
, ktoré odkazuje na názvy zdrojov nájdené v balíku aplikácie pre cieľ.
class TargetAppBContentManager : ContentManager { var content: [Content] { return [ Content(name: TargetAppBContentIdentifier.videoOneName.rawValue, image: TargetAppBImagePreviewIdentifier.videoOnePreview.rawValue, video: TargetAppBImageVideoIdentifier.videoOneVideo.rawValue), Content(name: TargetAppBContentIdentifier.videoTwoName.rawValue, image: TargetAppBImagePreviewIdentifier.videoTwoPreview.rawValue, video: TargetAppBImageVideoIdentifier.videoTwoVideo.rawValue), Content(name: TargetAppBContentIdentifier.videoThreeName.rawValue, image: TargetAppBImagePreviewIdentifier.videoThreePreview.rawValue, video: TargetAppBImageVideoIdentifier.videoThreeVideo.rawValue), ] } }
Ďalej je TargetAppBContentManager
, konkrétna implementácia použitá pre druhý cieľ aplikácie. Vyzerá veľmi podobne ako prvá implementácia, s výnimkou aplikácie B sú identifikátory odlišné.
Po vytvorení oboch implementácií na ne teraz môžete nepriamo odkazovať vo svojom kóde nastavením typu objektu na ContentManager
. Pozrite si príklad ViewModel nižšie:
@Observable class VideoListViewModel { var contentManager: ContentManager init(contentManager: ContentManager) { self.contentManager = contentManager } }
ViewModel očakáva, že cez inicializátor prejde určitý typ ContentManager
. ViewModel môže prejsť oboma typmi ContentManager
a naďalej fungovať podľa očakávania. To tiež znamená, že ViewModel možno znova použiť v oboch cieľoch aplikácie.
Posledná vec, ktorú musíte urobiť, je zabezpečiť, aby sa do fázy kompilácie zdrojov pridal správny ContentManager. V tomto prípade je aplikácia A odovzdaná TargetAppAContentMananger
ako súčasť svojich zdrojov a aplikácia B je odovzdaná TargetAppBContentManager
.
Posledná vec, ktorú musíte urobiť, je zabezpečiť, aby každý balík aplikácií obsahoval zdroje s názvami, ktoré sa zhodujú s identifikátormi používanými aplikáciou. Jednoduchým spôsobom je skontrolovať fázu zostavovania Copy Bundle Resources
pre každý cieľ aplikácie a zabezpečiť, aby na zdroje odkazoval správca obsahu. Ak nie, presuňte ich z projektu Xcode do fázy zdrojov kopírovania.
Testovanie si vyžaduje trochu času a starostlivosti, pretože ak zdroj, na ktorý sa odkazuje, nie je v balíku dostupný, nedostanete chybu pri kompilácii. Počas behu dôjde k havárii!
Dobrým spôsobom, ako automatizovať kontrolu, je napísať test jednotky, ktorý potvrdí, že všetky zdroje, na ktoré odkazuje ContentManager
sú uložené v balíku. Ak test pri spustení zlyhá, viete, že v balíku chýba zdroj.
Ak ste sa dostali až sem, mali by ste mať dobrý nápad, ako preniesť svoju aplikáciu na iné platformy Apple.
Na zavŕšenie tohto príspevku vám nechám niekoľko tipov a zdrojov, ktoré odporúčam:
Ak pridávate podporu Apple Vision do existujúcej aplikácie, najprv migrujte čo najviac kódu z UIKit do SwiftUI. Keď ste videli rýchlosť existujúcej aplikácie pracujúcej na Vision Pro pri migrácii na SwiftUI, je užitočné sa na ňu spoľahnúť.
Prečítajte si pokyny spoločnosti Apple o prenesení existujúcich aplikácií do systému visionOS . Poskytuje užitočné tipy a návrhy, ako to urobiť a ako využiť výhody funkcií visionOS.
Ak uvažujete o spustení novej multiplatformovej aplikácie sami, v Xcode je k dispozícii karta Multiplatform, ktorá poskytuje množstvo šablón aplikácií na použitie. K téme je aj video z WWDC 2022 .
Ak by ste chceli vidieť príklady aplikácií fungujúcich na viacerých platformách, odporúčam vám pozrieť si moje osobné aplikácie Christmas Chill a Ocean Chill . Ide o dve aplikácie fungujúce v rámci tvOS a Vision Pro, ktoré sú vytvorené z jednej kódovej základne. (Podpora tvOS pre Ocean Chill už čoskoro!)