Ciao a tutti, sono Francesco Noya, un nuovo autore di questa community di programmazione iPhone, e come primo articolo ho deciso di parlarvi di “estensioni di file”. A partire dalla versione 3.2 dell’SDK di Apple, infatti, è possibile registrare le estensioni di file che un’applicazione è in grado di gestire. Questo permette, ad esempio, di creare il proprio lettore di pdf da utilizzare quando si apre un allegato in Mail o con Safari. In questo tutorial vedremo come creare una piccola applicazione che apre automaticamente i file pdf e li mostra in una UIWebview.

Per prima cosa creiamo una “Window-based application” e diamole un nome (io l’ho chiamata “PDFFromSafari”).

A questo punto modifichiamo il file info.plist per registrare le estensioni che la nostra applicazione sarà in grado di manipolare. Per farlo impostiamo la visualizzazione del file come “Source Code File” in modo da vedere la sua struttura come file xml.


t065 registrare estensioni file iphone 01

Il file aperto si presenta più o meno così:


t065 registrare estensioni file iphone 02

Andiamo ad aggiungere le seguenti righe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
	<key>UIApplicationExitsOnSuspend</key>
	<true/>
 
	<key>CFBundleDocumentTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeIconFiles</key>
			<array>
				<string></string>
			</array>
			<key>CFBundleTypeName</key>
			<string>NSPasteboardTypePDF</string>
			<key>CFBundleTypeRole</key>
			<string>Viewer</string>
			<key>LSHandlerRank</key>
			<string>Alternate</string>
			<key>LSItemContentTypes</key>
			<array>
				<string>com.adobe.pdf</string>
			</array>
		</dict>
	</array>

Analizziamo quello che abbiamo scritto:

1
2
<key>UIApplicationExitsOnSuspend</key>
<true/>

Questa opzione impone all’applicazione di chiudersi quando si preme il pulsante dell’iPhone anziché entrare in Background. Ovviamente questo si applica solo se il dispositivo su cui lavoriamo è al iOS 4, altrimenti questo è il comportamento standard.

Le righe successive invece riguardano proprio la registrazione delle estensioni gestite dall’applicazione.

In particolare:

1
<key>CFBundleTypeIconFiles</key>

Contiene un array di stringhe contenenti il percorso all’icona che viene associata al file nel menù contestuale dei programmi che lo possono aprire.

1
<key>CFBundleTypeName</key>

Ha una stringa con il nome del tipo di documento che apre (nel nostro esempio “NSPasteboardTypePDF”).

1
<key>LSHandlerRank</key>

Raprresenta il ruolo che ha l’applicazione. Nel nostro caso con Alternate specifichiamo che si tratta di un modo alternativo per aprire il file

Infine:

1
<key>LSItemContentTypes</key>

contiene un Array di Uniform Type Identifiers (UTIs) che l’applicazione è in grado d’aprire. Nel nostro esempio i PDF: com.adobe.pdf

Ora che abbiamo modificato il file info.plist salviamolo e andiamo a scrivere il codice dell’ applicazione. In particolar modo quello che facciamo è cambiare il metodo

1
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Dell’Application Delegate.

Ecco le modifiche da fare:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
 
	NSURL *urlFileEsterno = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
 
	if(urlFileEsterno != NULL){
		//carico il pdf in un oggetto NSData
		NSData *pdf = [[NSData alloc] initWithContentsOfURL:urlFileEsterno];
 
		UIWebView *webview = [[UIWebView alloc] initWithFrame:[[UIScreen mainScreen]bounds]]; 
		[webview loadData:pdf MIMEType:@"application/pdf" textEncodingName:nil baseURL:nil];
		[pdf release];
 
		webview.scalesPageToFit = YES;
		[window addSubview:webview]; 
		[webview release]; 	
 
		//elimino il file copiato sul dispositivo
		NSFileManager *filemanager = [NSFileManager defaultManager];
		[filemanager removeItemAtURL:urlFileEsterno error:NULL];
		[filemanager release];
 
	}else {
		//mostro un alert
		UIAlertView *popUp = [[UIAlertView alloc] initWithTitle:@"Aprimi da Safari"
														message:@"Prova ad aprirmi da Safari o dal programma Mail" 
													   delegate:self 
											  cancelButtonTitle:@"OK" 
											  otherButtonTitles:nil];
		[popUp show];
		[popUp release];
	}
 
 
    [window makeKeyAndVisible];
 
	return YES;
}

Vediamo di capire cosa fa:

1
NSURL *urlFileEsterno = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];

Questo è l’URL del file esterno. Ogni volta che un file viene aperto questi viene memorizzato all’interno della sottocartella inbox dei Documents dell’applicazione.

1
if(urlFileEsterno != NULL){

Controllo l’esistenza del file. Se il file esiste allora lo salvo all’interno di un oggetto NSData grazie al metodo:

1
NSData *pdf = [[NSData alloc] initWithContentsOfURL:urlFileEsterno];

Questo permette di aprire il file in una UIWebView con il metodo

1
[webview loadData:pdf MIMEType:@"application/pdf" textEncodingName:nil baseURL:nil];

Per finire istanziamo un oggetto NSFileManager che si occupa di eliminare il file creato (Ovviamente nulla ci vieta di tenerlo):

1
2
3
	NSFileManager *filemanager = [NSFileManager defaultManager];
	[filemanager removeItemAtURL:urlFileEsterno error:NULL];
	[filemanager release];

(NB. Il metodo removeItemAtURL è stato introdotto dalla SDK 4, per cui se state usando versioni precedenti dovrete usare qualche accorgimento e cambiare il metodo con removeItemAtPath).

Quello che fa il blocco dell’else è semplicemente visualizzare un alert quando si apre l’applicazione in maniera “normale”, senza passare da Safari (o chi per esso).

Salviamo ed eseguiamo… dal momento che il simulatore non ha Mail, ho testato il funzionamento dell’app aprendo Gmail da Safari ed andando ad aprire una mail con allegato un pdf.

Vediamo il risultato:

se avvio l’applicazione:


t065 registrare estensioni file iphone 03

Quando apro il pdf in Safari compare il menu Apri in:


t065 registrare estensioni file iphone 04

Lo stesso pdf aperto nella nostra applicazione:


t065 registrare estensioni file iphone 05

Considerazioni Finali

Ciò che rende molto potente il meccanismo delle UTI è che permette di definire anche tipi di file proprietari. Se siete interessati ad un esempio che include la definizione di UTI personali vi rimando a questa discussione su StackOverflow (in Inglese) al seguente indirizzo.

Per avere invece maggiori informazioni, invece, sulla definizione dei CFBundleDocumentTypes questi sono alcuni link alla documentazione Apple:

http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/CoreApplication/CoreApplication.html#//apple_ref/doc/uid/TP40009370-CH6-SW11

http://developer.apple.com/iphone/library/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-101685-TPXREF107

http://developer.apple.com/iphone/library/documentation/uikit/reference/UIDocumentInteractionController_class/Reference/Reference.html


Icona Download Se avete problemi con il tutorial, questo è il nostro file di progetto.