Come scrivere il plugin OS X Finder

Sto cercando una guida o un codice di esempio per scrivere plugin per Mac OS X Finder? Vorrebbe sapere come fare alcune semplici azioni:

  1. aggiungere sovrapposizioni di immagini alle icone
  2. aggiungere voci del menu contestuale
  3. ascolta le modifiche ai file

Ho trovato le seguenti due risorse:

  • Scrittura di plugin del menu contestuale per OS X : un documento obsoleto del 2002 che utilizza l’API COM per Mac OS X 8/9.
  • SCPlugin : applicazione Mac SVN open source che include un plug-in Finder.

Sono tentato di rivedere il codice SCPlugin , ma speravo di trovare un campione più semplice da digerire.

Purtroppo, programmare un plugin per Finder richiede ancora di sporcarsi le mani con COM. Se si guarda il sottoprogetto SCFinderPlugin del progetto SCPlugin, si scoprirà che segue esattamente le stesse tecniche delineate nel primo collegamento, inclusa l’impostazione di un vtable per COM, la scrittura di funzioni AddRef / ReleaseRef e così via. La scrittura di un plug-in, in cui si gestiscono contemporaneamente la gestione della memoria del carbonio vecchia scuola, la gestione della memoria in stile COM e la gestione della memoria del carbonio Cocoa / nuovo stile, può essere un dolore incredibile, e ignora totalmente il fatto che sarete interagire in tre o più API radicalmente differenti, con diverse convenzioni di denominazione e semantica chiamante. Definire la situazione istericamente povera sarebbe un eufemismo.

Sul lato positivo, il Finder di Mac OS X 10.6 Snow Leopard è stato completamente riscritto in Cocoa – e con questo le interfacce dei plugin sono notevolmente superiori. Se sei abbastanza fortunato da trovarti in una situazione in cui puoi effettivamente bersagliare Snow Leopard, probabilmente dovresti prendere un abbonamento ADC Premier o superiore, scaricare i build prerelease e il codice contro quello. Inoltre, il tuo plugin potrebbe non funzionare su 10.6 in ogni caso senza una riscrittura di Cocoa, quindi potrebbe essere sensato dare un’occhiata a Snow Leopard prima che venga rilasciato, a prescindere.

Il progetto di esempio Overlay dell’icona Finder rappresenta un esempio semplice e molto semplice, ma effettivamente funzionante, della risposta seguente.

https://github.com/lesnie/Finder-Icon-Overlay

So che è così vecchio, ma alcuni potrebbero essere ancora interessati all’argomento (?)

Ecco cosa ho fatto sotto Leopard (10.6). All’inizio sono necessarie le intestazioni di Finder appropriate. Usa lo strumento dump di class per ottenerlo. Quindi scrivi il tuo codice come plugin SIMBL (consulta la documentazione su come farlo), procedendo con alcuni metodi. Ad esempio per disegnare qualcosa su un’icona in ListView, drawIconWithFrame: il metodo del metodo TIconAndTextCell deve essere sovrascritto.

Ecco il codice per il metodo swizzling:

 + (void) Plugin_load { Method old, new; Class self_class = [self class]; Class finder_class = [objc_getClass("TIconAndTextCell") class]; class_addMethod(finder_class, @selector(FT_drawIconWithFrame:), class_getMethodImplementation(self_class, @selector(FT_drawIconWithFrame:)),"[email protected]:{CGRect={CGPoint=dd}{CGSize=dd}}"); old = class_getInstanceMethod(finder_class, @selector(drawIconWithFrame:)); new = class_getInstanceMethod(finder_class, @selector(FT_drawIconWithFrame:)); method_exchangeImplementations(old, new); } 

Sto ignorando il metodo “drawIconWithFrame:” con il mio metodo “FT_drawIconWithFrame:”. Di seguito è riportata l’implementazione di esempio per questo metodo.

 - (void) FT_drawIconWithFrame:(struct CGRect)arg1 { [self FT_drawIconWithFrame:arg1]; if ([self respondsToSelector:@selector(node)]) { if ([[[[NSClassFromString(@"FINode") nodeWithFENode:[(TNodeIconAndNameCell *)self node]] fullPath] lastPathComponent] hasPrefix:@"A"]) [myPrettyIconOverlayImage drawInRect:NSMakeRect(arg1.origin.x, arg1.origin.y, arg1.size.height, arg1.size.height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; } } 

In pratica disegna “myPrettyIconOverlayImage” su ogni icona per il file con il nome del file che inizia con la lettera “A”. Questa logica dipende da te.

Presta attenzione a questa riga: [self FT_drawIconWithFrame:arg1]; questo è come chiamare ‘super’ per ottenere un’icona e un nome normali, ecc. Lo so, sembra strano, come il loop, ma in realtà non lo è. Quindi connettiti al plugin SIMBL, installa SIMBL e … esegui.

A causa delle modifiche apportate a Lion, alcuni lavori devono essere eseguiti da zero (creare un nuovo file “Finder.h” con tutte le dichiarazioni necessarie in esso, trovare classi e metodi appropriati per l’override), ma questa tecnica funziona ancora.

Happy hacking!

Per Yosemite (MacOS 10.10 e successivi), puoi utilizzare il framework FinderSync di Apple, che consente alle estensioni del Finder di:

  • Esprimere interesse in specifiche gerarchie di cartelle
  • Fornisci “badge” per indicare lo stato degli oggetti all’interno di tali gerarchie
  • Fornisci voci di menu dinamiche nel menu contestuale del Finder, quando gli elementi selezionati (o la destinazione della finestra) si trovano in tali gerarchie
  • Fornire una voce della barra degli strumenti che visualizza un menu con elementi dinamici (anche se la selezione non è correlata)

Non esiste un sistema di plugin ufficiale o supportato per il Finder. A partire da OS X 10.6, sarà necessario inserire il codice nel processo Finder e sovrascrivere i metodi dell’objective C nel processo Finder.

L’ho fatto per un progetto proprietario. Posso dirvi che la ragione per cui non ci sono esempi o tutorial per questo è perché è un’attività di sviluppo molto difficile e dispendiosa in termini di tempo. Per questo motivo, ci sono molti incentivi per le persone o le organizzazioni che hanno compiuto questo compito per proteggere da vicino le specifiche del loro processo.

Se esiste un modo per raggiungere l’objective utilizzando l’API dei servizi, fallo. Scrivere un plugin per Finder ti porterà 1-2 mesi solidi di accurato sviluppo e una conoscenza ragionevolmente profonda degli interni di C e di Objective-C.

Se sei ancora convinto di volerlo fare, prendi mach_star . In bocca al lupo.

Per quanto ne so, non esiste un’architettura plugin ufficiale per il Finder. Potrebbe essere ansible aggiungere sovrapposizioni di immagini a icone tramite un’applicazione esterna senza dover agganciare il Finder, anche se non sarebbe al volo. Non penso che ci sia un modo per aggiungere voci di menu contestuali oltre a Folder Actions e Automator. È inoltre ansible esaminare la scrittura di un’applicazione esterna per monitorare le modifiche del file system utilizzando l’ API FSEvents .

Ecco una soluzione completa per i badge icona del Finder e i menu contestuali in Lion e Mountain Lion, utilizzando le tecniche descritte da Les Nie.

Liferay Nativity fornisce un bundle di scripting che sfrutterà i metodi Finder rilevanti e un client Java per l’impostazione di icone e menu contestuali. Include anche progetti equivalenti per Windows e Linux.

Il progetto è open source sotto LGPL, quindi sentiti libero di contribuire con eventuali correzioni di bug o miglioramenti!

Le raccolte sono sottili; non è mai stato chiaro per me se i Plugin del Finder sono effettivamente supportati. Alcuni altri indizi, però:

  • SampleCMPlugIn – Naturalmente basato sul carbonio, poiché lo è anche Finder. Nota che quasi tutti i plugin per Finder probabilmente smetteranno di funzionare con 10.6.
  • Automator può salvare le cose come un “plugin del Finder”. È una versione più supportata di ciò che stai discutendo, ma ovviamente meno flessibile.

Per aggiungere overlay icona Finder / File Browser e menu contestuali, in modo multipiattaforma, da Java, dai un’occhiata alla libreria Nativity Liferay .

Ne parlo anche in un altro post SO , che contiene anche collegamenti ai documenti e alle API di Apple “Finder Sync”.