Marzipan hacken

Hoe we onze iOS-apps op Mac draaiend wisten te krijgen door Apples inofficiële Marzipan-technologie te hacken.

Marzipan hacken

Hoe wij nu al onze iOS-apps op Mac draaien

Toen Apple op WWDC 2018 een sneak preview van Marzipan gaf, waren veel Q’ers meteen enthousiast. Ein-de-lijk de mogelijkheid om onze iOS-apps naar de Mac over te zetten! Als iOS-developer lijkt het me geweldig, als de apps van bijvoorbeeld Rijksmuseum en Volkskrant óók op mijn Mac werken. Voor opdrachtgevers is een losse Mac-app nooit een prioriteit, maar met de belofte van Marzipan zouden we weleens heel makkelijk universele apps kunnen maken voor zowel iPhones en iPads áls Macs.

Enige minpuntje was dat Apple de Marzipan-technologie voorlopig alleen beschikbaar maakte voor eigen apps, zoals Apple Nieuws en Aandelen. Dat weerhield Q’er Tom niet om alvast in Marzipan te duiken: hij wilde weten hoe het werkt en wat we er nu al mee kunnen. Sterker nog: terwijl Apple nog een officiële naam voor deze nieuwe technologie bekend moet maken — en ik het hier dus maar gewoon ‘Marzipan’ blijf noem en — lukte het Tom met wat kunst- en vliegwerk een demo-app in elkaar te hacken. In zijn presentatie hieronder vertelt hij hoe hem dat lukte.

Onder de motorkap
iOS heeft altijd al een gedeelde basis gehad met macOS. Alleen maken developers voor de UI gebruik van AppKit op de Mac, waar ze op iOS UIKit gebruiken. Apple brengt met het Marzipan-project UIKit naar de Mac en maakt daarvoor de nodige aanpassingen. Bijvoorbeeld het toevoegen van ondersteuning voor vensters die je van formaat kan veranderen, menu’s en een muis. De Woning-, Aandelen-, Dictafoon- en Nieuws-apps van Apple maken gebruik van een experimentele versie van Marzipan.

De huidige tech stacks voor macOS- en iOS-apps — met Marzipan komt UIKit dus ook naar macOS

Deze vier apps draaien op een bijzondere manier: in plaats van één proces zoals gebruikelijk maken deze apps gebruik van twee processen. Een AppKit- en een UIKit-deel die samenwerken om een complete app-ervaring te bieden. De UIKitHostApp is het AppKit-deel dat bij het opstarten het icoon en de naam overneemt van het UIKit-deel. Vervolgens maakt dit proces een venster en een menubalk, zodat alle basisonderdelen voor een Mac-app er zijn. Ook verzorgt deze host-app de vertaling van muisinvoer naar touch events.

Het andere proces draait UIKitCore. Hier wordt de UIKit-interface van de app daadwerkelijk getekend en draait de code die je normaal op iOS zou draaien. UIKit op de Mac heeft allerlei extra uitbreidingen gekregen van Apple (die nog niet publiek zijn) om bijvoorbeeld menu-items toe te kunnen voegen en communicatie uit te kunnen voeren. Of om een alert te kunnen tonen. Deze alert wordt dan doorgegeven naar de UIKitHostApp die het als een macOS opgemaakte alert getoond.

Overigens is het interessant om te zien dat UIKit op macOS geen functionaliteit meer bevat die op iOS al was aangemerkt als verouderd. Al deze functies, zoals de oude UIWebView, zijn verwijderd. Alleen de nieuwe varianten hiervan, zoals WKWebView, zijn beschikbaar.

De twee processen van Apples Dictafoon-app op macOS Mojave

Eigen iOS-apps op Mac draaien
Vlak nadat Apple de beta van macOS Mojave uitbracht, realiseerden mensen zich dat UIKit-apps al heel lang op de Mac draaien in de iPhone en iPad simulator. Steve Troughton-Smith is hier ingedoken en heeft een Marzipanify-tool gemaakt waarmee je een UIKit-app voor de simulator kan ‘omhacken’ naar een app die draait op de Mac. Om de app op te kunnen starten moet je overigens wel een aantal beveiligingen van macOS uitschakelen, dus zelfgemaakte Marzipan-apps draaien is geheel op eigen risico!

Op basis van het werk van Steve heeft Tom geprobeerd onze eigen apps draaiend te krijgen op Mac. Hij ontdekte echter een paar struikelblokken bij het converteren van Primephonic en PostNL, zoals closed source-componenten van andere partijen (de Firebase SDK en Realm), maar ook iOS-features die niet beschikbaar zijn op de Mac (SFViewController en het kompas).

Tijd voor plan B: niet proberen een hele productie-app te draaien, maar een component daaruit. In de Rijksmuseum-app kun je inzoomen op hoge resolutie afbeeldingen van kunstwerken. Deze viewer gebruikt Swift, UIKit en CATiledLayer samen met networking om de data in te laden. Dat blijken API’s te zijn die al goed en soepel werken op macOS!

Vervolgens bleef het toch kriebelen om een meer complete app te draaien en is Tom aan de slag gegaan met zijn hobbyproject, de app Trein. Hier kon hij makkelijker incompatible API’s uit slopen. Na het uitschakelen van Realm, Siri intents, UINotificationGenerator en het deployment target op iOS 12 zetten werkte een en ander!

Steve Troughton-Smit in een Twitter draadje over de toekomst van Mac apps

We zijn er nog niet
Marzipan is officieel nog niet uit. Het is dus ook nog lastig om ermee te spelen en het uit te proberen. Veel libraries werken niet goed en je moet je app toch nog behoorlijk aanpassen om ‘m te laten werken. Ondanks dat is het erg leuk om rond te hacken en te kijken hoe alle API’s werken, welke private API’s er zijn en zo te leren over hoe een en ander in elkaar zit.

De apps van Apple zelf zijn ook nog voor verbetering vatbaar. Er gebeurt nog heel veel in een venster, waar je op macOS zou verwachten dat het losse vensters zijn, zodat je ze even aan de kant kan slepen. Veel controls zijn nog 1-op-1 touch controls waardoor het soms raar voelt ze te bedienen met je muis en toetsenbord. En wanneer je moet rechtsklikken of iets lang vast moet houden, werkt soms nog een beetje onduidelijk.

Overigens zijn er ook goede details die Apple heeft gefixt. Zo is er een extra highlight om een tekstveld toegevoegd zoals gebruikelijk op macOS, worden alerts afgevangen en worden tabjes en knoppen bovenin de app getoond in plaats van onderin. Dit geeft aan dat Apple deze dingen nu al aan het oplossen is, ook al is Marzipan nu nog slechts een ‘sneak peek’.

De toekomstdroom
Ik denk dat Apple door UIKit te pakken een hele goede basis heeft waarop veel iOS-ontwikkelaars Mac-apps kunnen gaan bouwen. Het is een aanpak waarmee Apple elk jaar een verbeterslag kan doen waar alle bestaande apps van profiteren. Hopelijk komt er zo een ecosysteem waarbij het net zo makkelijk is om een iPad-app klaar te stomen voor de Mac, als het nu is om een iPhone-app beschikbaar te maken op de iPad. Daarmee kunnen een hoop interessante apps ook beschikbaar worden op een platform waar we nu vaak af moeten met een website.

Volgens mij is het goed dat Apple niet geprobeerd heeft destijds Mac-apps naar de iPhone te brengen en dat nu ook niet ziet als de oplossing. De aanpak om het momenteel dominante platform als uitgangspunt te pakken, met de bijbehorende ontwikkelaars-gemeenschap, is veel krachtiger. Onderstaande tweet van Throughton-Smit vat dat goed samen:

Zelf aan de slag
Zin gekregen om zelf aan de slag te gaan met Marzipan? Op GitHub vind je een demo app met instructies hoe je een en ander draaiende kan krijgen. In de talk “Hacking Marzipan, Running iOS apps on Mac” legt Tom uit hoe je hiermee aan de slag kan.


Heb jij ideeën over hoe we iOS-apps niet alleen naar macOS, maar ook naar tvOS, watchOS kunnen brengen? Solliciteer dan op onze huidige iOS-vacature of check onze afstudeeropdracht!