Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
Software
K vašim službám 6: naposledy vyhrazeno pro programátory
macosearly
15. ledna 2002, 00.00 | V minulém dílu jsme si připravili jednoduchoučkou aplikaci, která zobrazuje složky a soubory, a umožňuje nad nimi využití souborových služeb.
V minulém dílu jsme si připravili jednoduchoučkou aplikaci, která zobrazuje složky a soubory, a umožňuje nad nimi využití souborových služeb:
Ti, kdo minulý díl přeskočili, naleznou kompletní projekt na www.ocs.cz/Apps/MiniWM.tar.gz.
Dnes náš seriál o Services ukončíme tím, že si ukážeme, jak služby implementovat: doplníme do této aplikace službu "Select in MiniWM", která označený text interpretuje jako jméno složky nebo souboru, a danou složku či soubor zobrazí v browseru.
Základy
Zatímco využívat Services mohla aplikace čistě programově, s nabídkou služeb to tak jednoduché není: služby aplikací musí být k dispozici i když aplikace neběží (jak víme, systém aplikaci v případě potřeby automaticky spustí). Proto musí aplikace služby, jež nabízí, publikovat v nějakém srozumitelném a "zvenky čitelném" formátu.
Takový formát je díky dědictví NeXTStepu dávno k dispozici: jde o soubor Info.plist, který obsahuje všechny podstatné informace o aplikaci, a který je standardně uložen uvnitř její složky.
Máme-li připraven patřičný obsah souboru Info.plist, zbývající je triviální: při startu aplikace jen dáme systému na vědomí, který objekt se o poskytování Services stará — a implementujeme přímo požadované služby.
Soubor Info.plist
Obsah souboru Info.plist je vcelku jednoduchý: jde o slovník (tj. množinu dvojic <klíč, hodnota>); my do něj chceme přidat klíč "NSServices", jehož hodnotou je pole — každá položka tohoto pole representuje jednu službu. Údaje o službě jsou určeny (vnořeným) slovníkem, jehož klíče jsou (mj.):
- "NSMenuItem": název položky menu Services. Kvůli možnosti lokalizace jde o (opět vnořený) slovník, jehož klíči mohou být jazyky; základní hodnota má klíč "default";
- "NSPortName": v našem případě obsahuje vždy jméno aplikace;
- "NSMessage": jméno zprávy, prostřednictvím které bude požadavek předán aplikaci (k tomu si za chvilku řekneme více);
- "NSSendTypes": seznam typů dat, nad nimiž služba může pracovat;
- "NSReturnTypes": seznam typů dat, jež služba může vracet.
Při konkrétní přípravě tohoto obsahu však bohužel již narazíme na nový ProjectBuilder: specifikovat v něm Services přímo a jednoduše není možné, a neexistuje ani žádná snadná cesta typu "copy & paste" — musíme se proklikat do jakýchsi záhadných nastavení, a tam seznam připravit ručně pomocí velmi nešikovného editoru. To vše se týká verse 1.1; snad se to časem zlepší; prozatím sledujte se mnou:
- v záložkách při levém okraji okna zvolíme "Targets";
- vybereme jediný "target" MiniWM; v prostoru, kde je normálně editovaný zdrojový soubor, se objeví panel s řadou speciálních nastavení;
- pomocí záložek v horní části tohoto panelu zvolíme "Application Settings";
- tlačítkem "Expert" v pravém horním rohu hned pod záložkami přepneme na editor souboru Info.plist.
Výsledek (už se specifikací naší nové služby) vidíme na následujícím obrázku:
Pomocí tlačítka "New Sibling" přidáme nový záznam, pojmenujeme jej "NSServices", změníme jeho typ na "Array", klepnutím na trojúhelníček vlevo jej otevřeme. Tlačítko se změní na "New Child" — přidáme jím položku 0, změníme její typ na "Dictionary", otevřeme jej... a tak dále. Nelekněte se, když vám editor pod rukou přehází položky (třídí je podle abecedy v nejnevhodnějších chvílích), a buďte rádi, že implementujeme jen jednu službu, protože editor vůbec nepodporuje práci se schránkou...
Podívejte se znovu na obrázek, kde je vidět kompletní záznam pro jednu službu "Select in MiniWM", která zpracovává textové řetězce (NSStringPboardType) a nic nevrací, a bude aplikaci "MiniWM" předána pomocí zprávy selectService.
Implementace
Máme-li za sebou přípravu souboru Info.plist, je to ostatní už jednoduché: nejprve řekneme systému, že všechny požadavky na služby řeší controller: stačí do metody awakeFromNib přidat jediný řádek
[NSApp setServicesProvider:self];
V rámci zprávy, kterou systém posílá pro provedení služby, mohou být předány až tři argumenty: prvním je sdílená schránka, ve které nalezneme data, nad kterými je třeba službu provést (a do které bychom uložili návratovou hodnotu, kdyby nějaká byla). Druhý a třetí zde nepoužijeme — jedná se o data, jež mohou rozlišovat různé služby v dynamických systémech, a prostor pro hlášení chyby. Aby bylo možné tyto argumenty pohodlně předat, doplní systém k našemu jménu služby (selectService) ještě ":userData:error:". Je tedy třeba naimplementovat metodu
-(void)selectService:(NSPasteboard*)pboard
userData:(NSString*)data error:(NSString**)error {
if ([[pboard types] containsObject:NSStringPboardType]) {
NSString *s=[pboard stringForType:NSStringPboardType];
[[browser window] makeKeyAndOrderFront:self];
if (![browser setPath:s]) NSBeep();
}
}
Vlastní implementace už snad je zřejmá: pokud jsme opravdu dostali textová data (defensivní programování!), vytáhneme je ze sdílené schránky do proměnné "s". Přemístíme okno do popředí příkazem makeKeyAndOrderFront:, a pokusíme se nastavit cestu v browseru na zadaný text — pokud se to nepodaří, pípneme (stejně dobře bychom samozřejmě mohli zobrazit komplexní chybovou hlášku).
Celý projekt i s těmito úpravami je uložen na www.ocs.cz/Apps/MiniWM2.tar.gz.
Aby to fungovalo...
Samozřejmě, že bezprostředně po zbuildování aplikace její služby k dispozici nebudou — systém musí nejprve upravit svou databázi všech služeb, a naši aplikaci mezi ně zahrnout. Aby se to stalo, musíme
- aplikaci uložit do některé ze složek /Applications nebo (v tomto případě daleko spíše) ~/Applications, či do některé ze složek jim podřízených;
- se odlogovat a znovu přilogovat.
V OpenStepu bylo odjakživa možné si velmi nepříjemné odlogování uspořit provedením jednoduchého příkazu make_services; Apple však tento příkaz najednou přestal podporovat — takže máme smůlu.
To je všechno
Systém služeb ovšem obsahuje další taje a kouzla — existují např. tzv. "Filtering Services", které zajišťují automatický import nejrůznějších formátů do aplikací, jejichž programátoři o nich neměli ani ponětí... To už by ale přesáhlo rámec tohoto seriálu.