XPC-diensten op macOS-app
Vóór XPC pakten we vroeger Sockets en Mach Messages (Mach Ports).
Het XPC-mechanisme biedt een alternatief voor sockets (of Mach Services met MIG) voor IPC. We zouden bijvoorbeeld een proces kunnen hebben dat fungeert als een “server” die wacht op clients om toegang te krijgen tot zijn API en een of andere dienst te verlenen.
XPC Services op applicaties
Wanneer we het hebben over XPC Services (hoofdletter ‘S’), verwijzen we naar de bundel genaamd XPC Service. Bundels in het Apple ecosysteem verwijzen naar entiteiten die worden vertegenwoordigd door een specifieke mappenstructuur. De meest voorkomende bundel die u tegenkomt zijn Application Bundles. Als u met de rechtermuisknop klikt op een toepassing (bijvoorbeeld Chess.app) en u selecteert Inhoud weergeven, dan ziet u een mappenstructuur. Terug naar XPC, applicaties kunnen meerdere XPC Service bundels hebben. U vindt ze in de Contents/XPCServices/ directory in de applicatiebundel. U kunt zoeken in uw /Applications directory en zien hoeveel van de toepassingen vertrouwen op XPC Services.
U kunt ook XPC Services binnen Frameworks (die een ander type Bundle).
Aanvullende voordelen van XPC Services
Het gebruik van XPC Services in onze apps stelt ons in staat om sommige functionaliteit op te splitsen in afzonderlijke modules (de XPC Service). We kunnen een XPC Service maken die belast kan worden met het uitvoeren van dure maar weinig voorkomende taken. Bijvoorbeeld een crypto-taak om willekeurige getallen te genereren.
Een ander bijkomend voordeel is dat de XPC Service op zijn eigen proces draait. Als dat proces crasht of wordt gedood, heeft dat geen invloed op onze hoofdapplicatie. Stel dat uw applicatie door de gebruiker gedefinieerde plugins ondersteunt. En de plugins zijn gebouwd met behulp van XPC Services. Als ze slecht zijn gecodeerd en crashen, hebben ze geen invloed op de integriteit van uw hoofdapplicatie.
Een bijkomend voordeel van de XPC Service is dat ze hun eigen rechten kunnen hebben. De applicatie heeft het recht alleen nodig als het gebruik maakt van een service die wordt geleverd door XPC Service die het recht vereist. Stel u voor dat u een app heeft die locatie gebruikt, maar alleen voor specifieke functies. U zou die functies kunnen verplaatsen naar een XPC Service en de locatie entitlement alleen aan die XPC Service kunnen toevoegen. Als uw gebruiker de functie die gebruik maakt van de locatie nooit nodig heeft, zal hij niet om rechten worden gevraagd, waardoor het gebruik van uw app betrouwbaarder wordt.
XPC en onze vriend launchd
launchd is het eerste proces dat op ons systeem draait. Het is verantwoordelijk voor het starten en beheren van andere processen, services en daemons. launchd is ook verantwoordelijk voor het plannen van taken. Het is dus logisch dat launchd ook verantwoordelijk is voor het beheer van XPC Services.
XPC Services kunnen worden gestopt als ze lange tijd inactief zijn geweest, of op verzoek worden gespawned. Al het beheer wordt gedaan door launchd, en we hoeven niets te doen om het te laten werken.
launchd heeft informatie over systeembrede beschikbaarheid van bronnen en geheugendruk, wie kan het beste beslissingen nemen over hoe we de bronnen van ons systeem het meest effectief kunnen gebruiken dan launchd
Implementeer XPC Services
Een XPC service is een bundel in de Contents/XPCServices directory van de hoofd applicatie bundel; de XPC service bundel bevat een Info.plist bestand, een executable, en alle bronnen die de service nodig heeft. De XPC-service geeft aan welke functie moet worden aangeroepen wanneer de service berichten ontvangt door xpc_main(3) Mac OS X Developer Tools Manual Page aan te roepen vanuit zijn hoofdfunctie.
Om een XPC-service in Xcode te maken, doet u het volgende:
- Een nieuw doel aan uw project toevoegen, met behulp van het XPC Service-sjabloon.
- Voeg een Copy Files-fase toe aan de build-instellingen van uw toepassing, die de XPC-service kopieert naar de Contents/XPCServices-directory van de hoofdapplicatiebundel.
- Voeg een dependency toe aan de build-instellingen van uw toepassing, om aan te geven dat deze afhankelijk is van de XPC-servicebundel.
- Als u een low-level (op C gebaseerde) XPC-service schrijft, implementeert u een minimale main-functie om uw event-handler te registreren, zoals in de volgende code-vermelding wordt getoond. Vervang my_event_handler door de naam van uw event handler-functie.
int main(int argc, const char *argv) {
xpc_main(my_event_handler);
// The xpc_main() function never returns.
exit(EXIT_FAILURE);
}
Als u een service op hoog niveau (gebaseerd op Objective-C) schrijft met NSXPCConnection, maakt u eerst een verbindingsdelegate-klasse die voldoet aan het NSXPCListenerDelegate-protocol. Implementeer vervolgens een minimale hoofdfunctie die een luisterobject maakt en configureert, zoals in de volgende code listing.
int main(int argc, const char *argv) {
MyDelegateClass *myDelegate = ...
NSXPCListener *listener =
;
listener.delegate = myDelegate;
;
// The resume method never returns.
exit(EXIT_FAILURE);
}
De service gebruiken
De manier waarop u een XPC service gebruikt, hangt af van of u werkt met de C API (XPC Services) of de Objective-C API (NSXPCConnection).
De Objective-C NSXPCConnection API gebruiken De Objective-C NSXPCConnection API biedt een interface op hoog niveau voor het op afstand aanroepen van procedures, waarmee u methoden op objecten in het ene proces vanuit een ander proces kunt aanroepen (meestal een toepassing die een methode in een XPC-service aanroept). De NSXPCConnection API serialiseert automatisch gegevensstructuren en objecten voor overdracht en deserialiseert ze aan de andere kant. Als gevolg hiervan gedraagt het aanroepen van een methode op een object op afstand zich als het aanroepen van een methode op een lokaal object.
Om de NSXPCConnection API te gebruiken, moet u het volgende maken:
- Een interface. Deze bestaat voornamelijk uit een protocol dat beschrijft welke methoden vanuit het remote proces moeten kunnen worden aangeroepen. Dit is beschreven in Ontwerpen van een interface
- Een verbindingsobject aan beide kanten. Aan de service kant, is dit eerder beschreven in De service maken. Aan de kant van de client is dit beschreven in Verbinding maken met en gebruik maken van een Interface.
- Een luisteraar. Deze code in de XPC service accepteert verbindingen. Dit wordt beschreven in Een verbinding accepteren in de Helper. Berichten.