AppleScript: Ottenere la cartella che contiene un file selezionato

Non ha senso, coma gran parte di AppleScript, ma si fa così:

tell application "Finder" to set vFilePath to container of aDroppedFile as alias as text

Perché non ha senso?
Perché per ottenere un percorso (una cartella) va chiesto al Finder di restituire on forma di testo (as text) un percorso di un oggetto passato come percorso (as alias).

Una qualunque omissione di casting nella stringa qui sopra non funziona.

Preso tutto?! su iTunes App Store

Preso tutto?!

Come sapete, di tanto in tanto faccio deliberatamente pubblicità.
Bene, in questo caso la pubblicità riguarda un’applicazione per iOS: Preso Tutto?!
L’applicazione è gratuita:

Preso Tutto?! richiede iOS 5. x o superiori, è un’applicazione semplice e quindi utile.

Con Preso Tutto?! potete creare delle liste di cose da portare in viaggio, inserendo quelle che vi servono o scegliendole da una di quelle predefinite, che potete comunque personalizzare.

Quando avete finito di aggiungere elementi alla lista (sono possibili più liste, ognuna con un suo nome, una data di partenza), Preso tutto?! vi consente di “spuntare” gli elementi.

Quindi Preso tutto?! vi permette di gestire completamente il viaggio.

Viaggi ricorrenti?
PresoTutto?! può salvare la lista in modo da poterla riutilizzare ogni volta, senza dover inserire tutto da capo.

Preso tutto?! avrà tutti gli aggiornamenti futuri gratuiti per chi l’ha scaricata. La potete migliorare voi scrivendo allo sviluppatore.

E, naturalmente, la trovate sull’iTunes App Store.

* * *

Ribadito che l’app è gratuita e quindi a farle pubblicità non prendo un soldino, credo che valga la pena di provarla.
Conosco personalmente chi l’ha scritta, ma ve la consiglierei anche se così non fosse; questa conclusione, benché trovata da povera gente, c’è parsa così giusta, che abbiam pensato di metterla qui, come il sugo di tutta la storia. La quale, se non v’è dispiaciuta affatto, vogliatene bene a chi l’ha scritta, e anche un pochino a chi l’ha raccomodata. Ma se in vece fossimo riusciti ad annoiarvi, credete che non s’è fatto apposta2.

* * *

  1. Preso tutto?! for iPhone 3GS, iPhone 4, iPhone 4S, iPhone 5, iPod touch (3rd generation), iPod touch (4th generation), iPod touch (5th generation) and iPad on the iTunes App Store.
  2. MANZONI, Alessandro – Promessi Sposi (I -)

Icone Retina per le applicazioni del Roam

apps

Ho aggiornato tutte le icone di tutte le applicazioni del Roam, in modo che rendano meglio sugli schermi retina:

PNG Preparator 0.1

pp

Il rilascio di IconCreator 0.1 Droplet2 come Software libero del Roam1 ha avuto un buon riscontro.

Ed io a domandarmi come chi lo usa potesse sopportare questo:

Nominatele nello stesso ordine in questo modo:

icon_16x16.png
icon_32x32.png
icon_32x32@2x.png
icon_128x128.png
icon_256x256.png
icon_512x512.png
icon_512x512@2x.png

Create una cartella con un nome a piacere seguito da .iconset, ad esempio cartella.iconset.
Trascinateci dentro le immagini che avete creato.
Duplicate le immagini seguenti con CMD – D:

icon_32x32.png
icon_256x256.png
icon_512x512.png

Nominatele nello stesso ordine in questo modo:

icon_16x16@2x.png
icon_128x128@2x.png
icon_256x256@2x.png

La vostra cartella deve contenere dieci immagini:

icon_16x16.png
icon_16x16@2x.png
icon_32x32.png
icon_32x32@2x.png
icon_128x128.png
icon_128x128@2x.png
icon_256x256.png
icon_256x256@2x.png
icon_512x512.png
icon_512x512@2x.png

No, dico, ma io che ho fatto l’informatico perché sono pigro, mi sarei rotto i coglioni già solo a leggerla una cosa del genere.

E infatti ho automatizzato tutto il processo che leggete qui sopra (eccetto la creazione delle icone, ed un giorno se volete vi spiego il perché è bene così).

Ed ecco PNG Preparator 0.13.

Ce ne sono due versioni, entrambe contenute nel download, ed una è una droplet.

* * *

  1. Roam – Conoscere Possibile: Software
  2. eDue – IconCreator 0.1 Droplet
  3. Roam – Conoscere Possibile: Software: PNG Preparator 0.1

IconCreator 0.1 Droplet

ic

Apple su OS X 10.8 non supporta più Icon Composer1,2, che faceva parte dei Graphic Tools di Xcode, e quindi per coloro che lo usavano si viene a creare un problema.

IconCreator 0.1 Droplet lo risolve e supporta anche gli schermi Retina.
Gratis.

* * *

  1. eDue – Ma farsi i cazzi propri no, eh?!
  2. eDue – Apple Xcode 4.4 e Icon Composer
  3. eDue – Pattine da montagna (wIP 0.8)
  4. eDue – Roam – Conoscere Possibile: Software

Apple Xcode 4.4 e Icon Composer HOWTO

Se vi siete accorti che da Xcode 4.4 è sparito Icon Composer, trovate la soluzione qui: Apple Xcode 4.4 e Icon Composer | eDue.

* * *

Con l’occasione, se volete rimuovere Xcode 4.2.x, ma non l’avete fatto al momento di installare Xcode 4.3 dall’AppStore (Xcode 4.3 si presenta come un package invece che come una serie di cartelle annidate in /Developer/ sul disco di avvio), avete due metodi.

Uno è quello di andare in /Developer/Library/ e lanciare da Terminale (come root, ovvero con sudo, se non l’avete abilitato) i due script di shell

uninstall-developer-folder
uninstall-devtools

L’altro è questo: xcode4.2 – XCode 4.3 – Uninstall XCode 4.2 – Stack Overflow.

Il secondo, la prossima volta che lanciate Xcode, risulta in questo:

Omonimia fra dischi e AppleScript

Se su una macchina avete montato due dischi con lo stesso nome (ad esempio uno interno ed uno esterno), se lanciate un AppleScript per farci qualcosa e ne scegliete uno, lui opera comunque su quello interno.
Anche se fate Drag’n’Drop 😦

Quanto sopra su Mac OS X 10.7.4 Build 11E53.

Generare la documentazione da Xcode

Utilizzando l’utility appledoc è possibile generare automaticamente la documentazione delle classi ObjectiveC direttamente da Xcode durante la build del progetto.

Installare appledoc

La prima cosa da fare è installare appledoc. Il modo migliore è clonare i sorgenti del progetto pubblicati su GitHub in XCode e compilarli, così come riportato dalla sezione Quick Install del readme di progetto oppure dal paragrafo “Installing appledoc” dell’articolo Providing Custom Documentation in Xcode.

Una volta verificato che appledoc sia installato lanciando da terminale il comando appledoc –help, possiamo procedere alla configurazione del progetto Xcode per il quale si intende generare la documentazione.

Configurazione della build del progetto Xcode

Ogni progetto Xcode per il quale si desidera produrre la documentazione, dovrà essere configurato in modo da aggiungere delle fasi di build che si occuperanno di lanciare lo script appledoc che genera la documentazione.

Questi sono i passi di configurazione da seguire:

  • aprire il progetto in Xcode e selezionarlo nel Project Navigator;
  • creare un nuovo Target usando il tasto Add Target in basso a sinistra nella parte centrale della finestra;
  • Xcode ci propone diverse tipologie di Target, la tipologia di Target che permette di eseguire degli script è Aggregate; scegliere quella relativa alla piattaforma del progetto (iOS o Mac OS X);
  • nel nuovo Target selezionare il tab Build Phases e aggiungere una nuova Build Phase di tipo Run Script usando il tasto Add Build Phase in basso a destra della parte centrale della finestra;
  • espandere la sezione Run Script appena creata ed inserire nel campo contraddistinto dal numero 1 lo script per generare la documentazione:
    /usr/bin/appledoc \
    –project-name “Project Name” \
    –project-company “Company Name” \
    –company-id com.company.id \
    –logformat xcode \
    –create-html \
    –keep-undocumented-objects \
    –keep-undocumented-members \
    –exit-threshold 2 \
    –ignore .m \
    –ignore UnitTest \
    /Path/To/Project/Folder“dove sostituire:
    Project Name con il nome del progetto
    Company Name con il nome dell’autore/azienda
    com.company.id con il dominio univoco (in stile java package) dell’autore/azienda
    /Path/To/Project/Folder con il path completo al folder di progetto
  • se si desidera avere una copia della documentazione in una cartella diversa da quella di default (/User_home_folder/Library/Developer/Shared/Documentation/DocSets/com.company.id.Project-Name.docset), creare una nuova Build Phase di tipo Run Script ed inserire al suo interno il seguente script:
    cp -R /User_home_folder/Library/Developer/Shared/Documentation/DocSets/com.company.id.Project-Name.docset “/Destination/Path
    dove sostituire:
    User_home_folder con la directory home dell’utente
    com.company.id con il nome dominio univoco usato nello script precedente
    Project-Name con il nome del progetto specificato nello script precedente, sostituendo con un trattino gli eventuali spazi.

Inserire i commenti nei sorgenti

Affinché la documentazione generata con dei contenuti, è necessario inserire all’interno dei degli header delle classi, e per tutti gli elementi che si vogliono documentare (classe, proprietà, metodi), dei commenti che rispettino la sintassi di appledoc che è molto simile a quella adottata da javadoc.

Questo è un esempio di commento per un metodo:
/**
* Create and returns the singleton instance.
*
* @param dataFile The data file name
* @return The singleton instance
* @exception NSException Raised when the singleton creation fails.
*/

Una guida completa alla sintassi di appledoc è riportata dalla documentazione presente sul sito del progetto.

Conclusioni

Ecco un esempio di quello che si otterrà per le proprie classi una volta generata la documentazione.

La documentazione generata da appledoc verrà visualizzata automaticamente in Xcode sia nel Quick Help inspector che nella sezione Documentation dell’Organizer.

Riferimenti

  1. Infinite Blog – Providing Custom Documentation in Xcode
  2. Gentle Bytes – Appledoc

Puntatori


I puntatori del C (e del C++) sono comodi, utili e facili da imparare, ed una volta imparati, oltre tutto, non si scordano più come l’equilibrio della bicicletta o dei pattini, e si usano con disinvoltura. Non potete ignorarli, sono troppo divertenti…

Indice

  1. Perché tanto odio?
  2. Cosa sono i puntatori
  3. Fico, non sembrano tanto antipatici
  4. Bibliografia & Links
  5. Copyright e Licenza

Perché tanto odio?

Se qualcuno di voi ha mai letto Totem Comics, ricorderà per forza un disegnatore di nome Edika. La sua sezione nella rivista era appunto intitolata “Perché tanto odio?”. Goliardia a parte, non sembra inopportuno parlare dei puntatori cominciando da questa domanda.
I puntatori sono antipatici a molti, un po’ come le sbucciature sulle ginocchia quando impariamo ad andare in bicicletta senza le rotelle, ma quando abbiamo imparato, tutti troviamo assolutamente divertente andare in bicicletta, e troveremmo le rotelle solo un impiccio.
L’antipatia delle sbucciature è solo un lontano ricordo, spesso rimosso, quando viene bilanciata dal divertimento delle curve a coltello o delle discese a manetta.
Preso il via, sta poi a noi decidere se usare la bicicletta solo per rilassanti passeggiate in pianura o per massacranti e gratificanti gare di ciclocross.
Quindi la tesi è: i puntatori sono solo antipatici all’inizio, ma poi è una goduria?
Si, io la vedo così.
Ah, beh, allora anche tu ammetti che i puntatori siano antipatici.
OK, i puntatori sono antipatici, ma solo all’inizio e non per colpa loro. Chiediamoci perché.
La colpa è di coloro che hanno scritto il C (ed il C++), ovvero per il modo in cui hanno definito la sintassi del linguaggio che opera sui puntatori.
Nella lingua italiana, o meglio nel linguaggio Italiano, gli stranieri trovano difficoltoso soprattutto l’uso di termini che assumono un senso diverso rispetto al contesto in cui sono utilizzati. Facciamo subito un esempio: ancora e ancora.
Anzi, dovremmo scrivere àncora ed ancóra, e comunque anche noi italiani avremmo primo, difficoltà a leggere e secondo a collocare queste due parole.
La prima, è il sostantivo che indica il pezzo di ferro con cui le navi attraccano in mare aperto, il secondo è l’avverbio che indica continuazione temporale, facciamo un esempio:
“La nave Alvaro è all’ancora a poche miglia dalla costa”, e “Acquisterei ancora un Mac anche se ne ho già due”.
“Aaah, ecco”?!
Antipatico no?
Beh, chi ha scritto il C (ed il C++) ha operato la stessa cattiveria nei confronti dei puntatori, per cui le tre funzioni che essi forniscono, le forniscono con due soli simboli.
Voi direte: avevano finito i simboli?
No, è proprio cattiveria…

Cosa sono i puntatori

Cosa volete che siano? Sono delle cose divertenti rese antipatiche dalla cattiveria di chi li ha invevntati.
Si, vabbè, non come sono, cosa sono.
V’accontento subito: sono delle variabili che contengono un indirizzo di memoria.
A cosa serve una variabile che contiene un indirizzo?
Beh, serve a fare tante cose, la prima delle quali è risparmiare memoria.
Ah, bella, io dichiaro una variabile che contiene un indirizzo di memoria, che magari contiene dei dati. Se usavo una variabile che identificava quei dati non facevo prima e sprecavo meno memoria?
No. Facciamo un esempio, ma solo per gradire. Mettiamo che voi abbiate definito una variabile che contiene un numero. Mettiamo anche che abbiate definito un’altra variabile, un puntatore, che contiene l’indirizzo della prima, che ricordiamo essere un numero; parleremo in questo caso di puntatore ad un numero, ed in particolare se il numero è un intero, parliamo di puntatore ad intero.
Se il numero è a virgola mobile, parleremo di puntatore a numero in virgola mobile, ecc.
OK, poi?
Poi cerchiamo di usare la prima variabile (il numero).
Cosa avviene? Avviene che se vogliamo sommare a quel numero un altro numero, dovremo usare una funzione (in C la funzione risponde al simbolo “+“) che prende il primo numero, prende il secondo numero e restituisce in una variabile la loro somma.
Lo immaginavate, vero? OK, allora facciamo io abbia dichiarato tre variabili:
int addendo1, addendo2, somma;
Adesso ammettiamo che in qualche modo io abbia assegnato ad addendo1 il valore 2, ad addendo2 il valore 3 ed li abbia sommati mettendo il risultato nella variabile somma:
somma = addendo1 + addendo2; // somma contiene il risultato di addendo1 + addendo2
Alla fine del tutto avrò tre variabili in memoria di cui una conterrà un valore interessante (somma) e due che non servono più ma sono ancora piene.
Questo avviene indipendentemente dal processo usato per arrivare alla somma, avrò comunque tre variabili piene e una sola che m’interessa.
Certo, avremmo potuto assegnare la somma ad una delle due variabili addendo, come in:
addendo1 = addendo1 + addendo2; // addendo1 contiene il risultato di addendo1 + addendo2
Così alla fine avremmo solo due variabili, di cui una utile.
Notate che finora non abbiamo sentito molto la mancanza della nozione “puntatore”…
Ora c’è un fatto.
Se a noi per un motivo che non sto qui a discutere non piacesse come la funzione somma del C calcola il suo risultato, potremmo decidere di scrivere noi una funzione di nome addizione che calcola la somma di due numeri e la restituisce in una variabile.
Immagino che una funzione di questo tipo avrebbe una forma simile a:
int addizione (int numero1, int numero2); // prototipo della funzione addizione
Potremmo chiedere all’utente il valore dei due numeri da sommare, metterli nelle solite variabili addendo1 e addendo2, poi chiamare la funzione che ho descritto per sommarli.
Accadrebbe, accade credetemi, che per fare questa somma benedetta io usi ad un certo punto cinque variabili di cui quattro uguali a due a due.
Quando chiamo la mia funzione, infatti, la macchina non le passa il valore contenuto in addendo1 e addendo2, ma una loro copia, cosa che in quel momento crea uno spreco di memoria del 100%, ovvero ne serve il doppio per fare la stessa cosa.
Alcuni hanno giustamente sottolineato che l’esempio fallisce, poiché quantitativamente potrebbe persino accadere che la dimensione dei puntatori sia maggiore della dimensione dei numeri in gioco, e che usare i puntatori in casi come questo sia persino penalizzante.
In effetti l’esempio vuole introdurre un concetto: chiamare una funzione passandogli dei valori, provoca la copia di questi valori.
Ora immaginate di passare come valori anziché due piccoli numeri interi due immagini, ad esempio per ottenere che una divenga la filigrana (o watermark) dell’altra.
In un caso come questo, senza troppo ragionare, si capisce che in un dato istante (al momento in cui chiamo la funzione) avrei in memoria (o peggio ancora in swap…) quattro immagini, uguali a due a due. E che cacchio, non si può evitare di sprecare tutta questa memoria?
Come no, usando i puntatori.
Usandoli, posso dire alla funzione di andarsi a leggere i valori dei parametri che le occorrono al loro indirizzo.
Capito il trucco?!

Fico, non sembrano tanto antipatici

No, infatti, immaginate appunto quando invece di passare ad una funzione due numeretti, gli passate delle strutture di memoria belle grandi e complesse, ed immaginate quanto spazio e tempo risparmiate, passando sempre un piccolo indirizzo, invece di tutta un’enciclopedia di codice binario.
E’ vero infatti che i puntatori sono variabili, ma è vero anche chi i puntatori sono variabili “piccole”.
Cosa voglio dire?
Mettiamo che un computer abbia la possibilità di trattare gli indirizzi a 64bit, ovvero che un indirizzo di memoria sia un numero che espresso in binario occupi al massimo 64 cifre binarie.
64 bit sono 8 byte.
Da questo discende che un puntatore a qualunque oggetto occupa al massimo quella dimensione.
Alcuni dati, come le immagini, raggiungono velocemente dimensioni nell’ordine dei MByte, ed un MByte sono già 1000 Kbyte.
Se io passassi ad una funzione la copia di una immagine, potrei passarle qualche MByte di dati (mettiamo anche solo un MByte), se le passo il suo indirizzo in memoria le passo al massimo (ne sono certo) 8 byte.
C’è una differenza di 125.000 volte.
Non si tratta quindi solo di contare il numero delle variabili, si tratta di pesarle.
Non solo, se tratto l’immagine con un filtro e l’immagine dopo il trattamento è raddoppiata di dimensione, il suo puntatore è sempre lo stesso quanto a dimensione.
Ma da dove deriva allora l’antipatia?
Vi servo subito, e cominciamo da come si dichiarano i puntatori in C (ed in C++):
int* pippo;
Ecco qui.
Delusi? vi aspettavate una cosa molto complicata? Beh, un po’ lo è. Provate a leggere quello che ho scritto.
Vediamo… int asterisco pippo puntevvirgola? E che vuol dire?
Eh, ve lo ho detto la cattiveria… Quella scritta si legge “pippo è un puntatore ad un intero”.
Beh, non sembra difficile…
Si, ma quale intero? Ah…
Infatti pippo, preso così non è che faccia molto, ed in effetti per il momento si è solo presentato, ha solo detto “sono pippo, un puntatore ad un numero intero”.
Per sapere a cosa “punta” pippo, dobbiamo assegnarlo (quella di prima è una dichiarazione, notate che non c’è l’uguale?), assegnarlo a cosa?
Ad un indirizzo, mi sembra ovvio, sennò che puntatore sarebbe? Mettiamo che abbiamo già dichiarato (ed assegnato):
int addendo1 = 2;
Scrivere: pippo = &addendo1;
Significa appunto dire che pippo (un puntatore ad intero) contiene l’indirizzo della variabile addendo1, o più brevemente possiamo dire che pippo punta addendo1.
A questo punto sappiamo che:

  • pippo è un puntatore ad un (tipo) intero
  • addendo1 contiene il numero 2
  • pippo contiene l’indirizzo di memoria di addendo1

Adesso arriva la parte violenta, sarebbe meglio che metteste i bambini a letto
Se chiedo a pippo cosa contiene, la risposta è scontata: un indirizzo di memoria.
Se io vedo pippo nel codice e magari so che è un puntatore perché ho visto che è stato dichiarato come puntatore, e mi domandassi a quale valore stia puntando in questo momento pippo, glielo devo chiedere, o meglio glielo chiedo e lo stampo a video, così lo posso leggere.
Se non fosse chiaro sto chiedendo a pippo: “qual è il valore contenuto all’indirizzo cui stai puntando adesso?”; insomma voglio che lui mi dica “2” tanto per dirsela tutta.
Beh, la domanda suona pressappoco così:
valore = *pippo; Ricorda qualcosa?
E certo che ricorda qualcosa, ricorda il modo in cui pippo è stato dichiarato!
Ah, si?! Leggetelo.
“pippo è un puntatore ad un uguale valore”?!
No, infatti questa non è una dichiarazione, è una assegnazione (c’è l’uguale), e quindi “asterisco pippo” non ci dice che pippo è un puntatore, ma ci dice che il valore contenuto alla posizione di memoria che pippo sta puntando da quando lo conosciamo, ovvero il numero 2 lo vogliamo mettere in una variabile di nome valore.
In pratica ecco la vera cattiveria, usare la stessa notazione (“asterisco pippo”) per fare due cose diverse:

  • int* pippo; ovvero pippo è un puntatore ad un (tipo) intero
  • valore = *pippo; ovvero il dato il cui indirizzo è contenuto da pippo il puntatore

Isomma:

  • int addendo1 = 2; // la variabile intera addendo1 è uguale a due
  • int* pippo; // pippo è un puntatore ad un (tipo) intero
  • pippo = &addendo1; // pippo punta all'indirizzo di addendo1
  • printf ("%d", *pippo); // stampa il numero 2
  • printf ("%p", pippo); /* stampa un numeraccio strano che probabilmente inizia per 0x e segue con una serie di numeri, che sono l'indirizzo di memoria a cui sta puntando pippo */

Perché tutto fosse più chiaro sarebbe bastato usare un terzo simbolo, come @ (at o chiocciola), per identificare il terzo membro della famiglia, e avremmo avuto uno strumento potente che non rompe l’anima a nessuno, guardate:

  • int* pippo; // pippo è un puntatore ad un (tipo) intero
  • pippo = &addendo1; // pippo punta all'indirizzo di addendo1
  • printf ("%d", @pippo); // stampa il valore puntato da pippo

Prometto, se un giorno dovessi scrivere un linguaggio, userei tre simboli per queste tre cose, i primi due presi dal C e il terzo, diverso dai primi due, per non farvi perdere tempo.
Ma ormai il danno è fatto, ed il C ed il C++ usano solo * e & per tutti e tre ed allora imparate una regoletta empirica ma efficace:

  • Se in una espressione compare &, si sta parlando di un indirizzo di memoria
  • Se in una espressione compare = seguito da un * e dal nome di una variabile si sta cercando il valore cui un puntatore si riferisce
  • Se in una espressione, che non sia un assegnamento, compare * si sta probabilmente dichiarando un puntatore

Tanto per dirsela tutta, in una espressione che non sia una dichiarazione, * e & producono risultati opposti, ovvero l’uno ci dà un valore e l’altro l’indirizzo di quel valore