Servicii XPC pe aplicația macOS
Înainte de XPC obișnuiam să luăm Sockets și Mach Messages (Mach Ports).
Mecanismul XPC oferă o alternativă la socket-uri (sau servicii Mach folosind MIG) pentru IPC. Am putea avea, de exemplu, un proces care acționează ca un „server” care așteaptă ca clienții să îi acceseze API-ul și să furnizeze un anumit serviciu.
Servicii XPC pe aplicații
Când vorbim despre Servicii XPC (cu „S” mare), ne referim la pachetul numit XPC Service. Bundle-urile din ecosistemul Apple se referă la entități reprezentate de o anumită structură de directoare. Cele mai frecvente pachete pe care le întâlniți sunt pachetele de aplicații. Dacă faceți clic dreapta pe orice aplicație (De exemplu, Chess.app) și selectați Show content (Afișare conținut), ceea ce veți găsi este o structură de directoare. Revenind la XPC, aplicațiile pot avea mai multe pachete de servicii XPC. Le veți găsi în directorul Contents/XPCServices/ din cadrul pachetului de aplicații. Puteți căuta în directorul /Applications și să vedeți câte dintre aplicații se bazează pe XPC Services.
De asemenea, puteți avea XPC Services în interiorul Frameworks (care sunt un alt tip de Bundle).
Beneficii suplimentare ale XPC Services
Utilizarea XPC Services în aplicațiile noastre ne permite să rupem anumite funcționalități în module separate (The XPC Service). Am putea crea un Serviciu XPC care se poate ocupa de rularea unor sarcini costisitoare, dar puțin frecvente. De exemplu, unele sarcini criptografice pentru a genera numere aleatoare.
Un alt beneficiu suplimentar este că Serviciul XPC rulează pe propriul proces. Dacă acel proces se blochează sau este ucis, nu afectează aplicația noastră principală. Imaginați-vă că aplicația dvs. suportă plugin-uri definite de utilizator. Iar pluginurile sunt construite cu ajutorul serviciilor XPC. Dacă acestea sunt prost codate și se prăbușesc, nu vor afecta integritatea aplicației dvs. principale.
Un beneficiu suplimentar al Serviciului XPC este că acestea pot avea propriile drepturi. Aplicația va avea nevoie de entitlement doar atunci când utilizează un serviciu furnizat de XPC Service care necesită acest entitlement. Imaginați-vă că aveți o aplicație care utilizează localizarea, dar numai pentru anumite funcții. Ați putea muta aceste caracteristici într-un serviciu XPC și ați putea adăuga dreptul de localizare numai la acel serviciu XPC. Dacă utilizatorul dvs. nu are niciodată nevoie de caracteristica care utilizează locația, nu i se vor solicita permisiuni, ceea ce face ca utilizarea aplicației dvs. să fie mai de încredere.
XPC și prietenul nostru launchd
launchd este primul proces care rulează pe sistemul nostru. Se ocupă de lansarea și gestionarea altor procese, servicii și demoni. launchd se ocupă, de asemenea, de programarea sarcinilor. Așa că este logic ca launchd să fie responsabil și de gestionarea serviciilor XPC.
Serviciul XPC poate fi oprit dacă a fost inactiv pentru o perioadă lungă de timp sau poate fi generat la cerere. Toată gestionarea este făcută de launchd, iar noi nu trebuie să facem nimic pentru ca acesta să funcționeze.
launchd are informații despre disponibilitatea resurselor la nivelul întregului sistem și despre presiunea asupra memoriei, cine mai bine decât launchd poate lua decizii cu privire la modul cel mai eficient de utilizare a resurselor sistemului nostru
Implementarea serviciilor XPC
Un serviciu XPC este un pachet în directorul Contents/XPCServices al pachetului principal de aplicații; pachetul de servicii XPC conține un fișier Info.plist, un executabil și orice resurse necesare serviciului. Serviciul XPC indică ce funcție să apeleze atunci când serviciul primește mesaje prin apelarea xpc_main(3) Mac OS X Developer Tools Manual Page din funcția sa principală.
Pentru a crea un serviciu XPC în Xcode, efectuați următoarele:
- Adaugați o nouă țintă la proiectul dumneavoastră, utilizând șablonul XPC Service.
- Adaugați o fază de copiere a fișierelor la setările de construcție ale aplicației dumneavoastră, care copiază serviciul XPC în directorul Contents/XPCServices al pachetului principal al aplicației.
- Adaugați o dependență la setările de construcție ale aplicației dumneavoastră, pentru a indica faptul că aceasta depinde de pachetul de servicii XPC.
- Dacă scrieți un serviciu XPC de nivel scăzut (bazat pe C), implementați o funcție principală minimă pentru a vă înregistra gestionarul de evenimente, așa cum se arată în următoarea listă de cod. Înlocuiți my_event_handler cu numele funcției dvs. de gestionare a evenimentelor.
int main(int argc, const char *argv) {
xpc_main(my_event_handler);
// The xpc_main() function never returns.
exit(EXIT_FAILURE);
}
Dacă scrieți un serviciu de nivel înalt (bazat pe Objective-C) folosind NSXPCConnection, creați mai întâi o clasă delegată de conexiune care să fie conformă cu protocolul NSXPCListenerDelegate. Apoi, implementați o funcție principală minimă care creează și configurează un obiect ascultător, așa cum se arată în următoarea listă de cod.
int main(int argc, const char *argv) {
MyDelegateClass *myDelegate = ...
NSXPCListener *listener =
;
listener.delegate = myDelegate;
;
// The resume method never returns.
exit(EXIT_FAILURE);
}
Utilizarea serviciului
Modul în care utilizați un serviciu XPC depinde de faptul că lucrați cu API C (XPC Services) sau cu API Objective-C (NSXPCConnection).
Utilizarea API Objective-C NSXPCConnection API-ul Objective-C NSXPCConnection oferă o interfață de nivel înalt de apelare a procedurilor la distanță care vă permite să apelați metode asupra obiectelor dintr-un proces de la un alt proces (de obicei o aplicație care apelează o metodă dintr-un serviciu XPC). API NSXPCConnection serializează automat structurile de date și obiectele pentru transmisie și le deserializează la celălalt capăt. Ca urmare, apelarea unei metode pe un obiect la distanță se comportă la fel ca și apelarea unei metode pe un obiect local.
Pentru a utiliza API-ul NSXPCConnection, trebuie să creați următoarele:
- O interfață. Aceasta constă în principal într-un protocol care descrie ce metode ar trebui să poată fi apelate din procesul la distanță. Acest lucru este descris în Proiectarea unei interfețe
- Un obiect de conexiune de ambele părți. Pe partea serviciului, acesta a fost descris anterior în Crearea serviciului. Pe partea clientului, acest lucru este descris în Conectarea la și utilizarea unei interfețe.
- Un ascultător. Acest cod din serviciul XPC acceptă conexiuni. Acest lucru este descris în Acceptarea unei conexiuni în Helper. Messages.