Gestire i pdf con IOS - Maurizio Moriconi - WhyMCA

Post on 18-Jun-2015

452 views 2 download

Transcript of Gestire i pdf con IOS - Maurizio Moriconi - WhyMCA

Maurizio Moriconi - @bugman79Mobilesoft

Gestire i PDF con iOS

giovedì 24 maggio 12

Chi sono: Maurizio Moriconi

2

• CTO presso Mobilesoft• Mobile Developer

• Co-founder• Main Developer

http://www.facebook.com/maurizio.moriconi

http://www.linkedin.com/in/bugman

@bugman79

giovedì 24 maggio 12

Editoria digitale

3giovedì 24 maggio 12

4giovedì 24 maggio 12

Funzionalità MobilePaper• Visualizzazione in portrait e landscape (2 pagine affiancate)

• Zoom della pagina tramite pinch o con doppio tap

• Possibilità di passare alle pagine successive o precedenti

• Visualizzazione delle pagine tramite elenco e/o miniature

• Visualizzazione dell'indice (capitoli e paragrafi del pdf)

• Memorizzazione dei segnalibri (preferiti)

• Scelta della musica di sottofondo

• Inserimento di note

• Ricerca di testo all'interno della rivista

• Disponibile su iOS ed Android

5giovedì 24 maggio 12

Editoria su iOS

• Varie possibilità:

– App Native– Uso di PDF con eventuale aggiunta di elementi nativi (multimedia ed interazione)

– HTML 5

6giovedì 24 maggio 12

Il formato Pdf• Portable Document Format

• File basato su un linguaggio di descrizione pagina

• Sviluppato da Adobe System nel 1993

• Nel 2007 è diventato standard ISO 32000

• Ci sono vari sottoformati (PDF/A, PDF/X, PDF/E...)

7giovedì 24 maggio 12

PDF/A• PDF/A (PDF/Archiving) per l’archiviazione a lungo

termine (ha 2 sottoformati /A-1a /A-1b)

• Standard ISO 19005-1:2005 dal 2005

• Basato sulla vesione 1.4 del formato PDF di Adobe

• Documenti “auto contenuti”– Include i font che utilizza!!– Include immagini, colori, altri dati–Non ci sono fonti esterne

• Nel sottoformato PDF/A-2 si basa PDF v. 1.7

8giovedì 24 maggio 12

PDF: specifichehttp://www.adobe.com/devnet/pdf/

pdf_reference.html

9

Ultima versione:

PDF Reference, sixth edition APDF version 1.7

1310 pagine!!!

giovedì 24 maggio 12

Uso della webview• Vantaggi

– Facile da realizzare

– Possibilità di usare pdf “online”

– Funzionamento dei link interni

• Svantaggi– Poca interazione lato utente

– Scrollview verticale

– Nessuna paginazione

10giovedì 24 maggio 12

Caricare Pdf in una webview

NSString *pdfPath = [[NSBundle mainBundle] pathForResource:@"file" ofType:@"pdf"];

NSURL *url = [NSURL fileURLWithPath:pdfPath];

NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];

[webView loadRequest:urlRequest];

11giovedì 24 maggio 12

Show me the code...

12giovedì 24 maggio 12

Uso di Quartz

• Motore di rendering di Darwin chiamato “per gli amici” con il nome di Core Graphics

• Quartz 2D: – libreria grafica ereditata da QuickDraw– usa il formato PDF per il disegno!!!– si basa sulla versione 1.4 Adobe PDF

13giovedì 24 maggio 12

Classi che ci interessano

• CGPDFDocument• CGPDFPage• CGPDFObject

• CGContext

14giovedì 24 maggio 12

Caricamento del Pdf#import <QuartzCore/QuartzCore.h>

NSURL *pdfURL = [[NSBundle mainBundle] URLForResource:@"TestPage.pdf" withExtension:nil];

CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);

// Prendo la prima paginaCGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);CGPDFPageRetain(page);

// Determino la grandezza del PDFCGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);pdfScale = self.imageView.frame.size.width/pageRect.size.width;pageRect.size = CGSizeMake(pageRect.size.width*pdfScale, pageRect.size.height*pdfScale);

15giovedì 24 maggio 12

Visualizzazione baseUIGraphicsBeginImageContext(pageRect.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);CGContextFillRect(context,pageRect); CGContextSaveGState(context);

CGContextTranslateCTM(context, 0.0, pageRect.size.height);CGContextScaleCTM(context, 1.0, -1.0); CGContextScaleCTM(context, pdfScale,pdfScale);!CGContextDrawPDFPage(context, page);CGContextRestoreGState(context); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); [self.imageView setImage:image]; CGPDFPageRelease(page);CGPDFDocumentRelease(pdf);

16giovedì 24 maggio 12

Show me the code...

17giovedì 24 maggio 12

Scorrimento pagine• Uso di scrollview con paginazione

• Creare una classe per la singola pagina ereditando da UIView

• Pre-caricare più pagine ma...

• Attenzione alla memoria!– Scaricare / Caricare una “finestra” di pagine

18giovedì 24 maggio 12

Pdf View- (id)initWithFrame:(CGRect)frame andPdfPage:(CGPDFPageRef)page{ self = [super initWithFrame:frame]; if (self) { pagina = page; pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); pdfScale = self.frame.size.width/pageRect.size.width; pageRect.size = CGSizeMake(pageRect.size.width*pdfScale, pageRect.size.height*pdfScale); } return self;}

- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0); CGContextFillRect(context,pageRect); CGContextSaveGState(context); CGContextTranslateCTM(context, 0.0, pageRect.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextScaleCTM(context, pdfScale,pdfScale);! CGContextDrawPDFPage(context, pagina); CGContextRestoreGState(context);}

19giovedì 24 maggio 12

Impostare numero di pagineNSURL *pdfURL = [[NSBundle mainBundle] URLForResource:@"test.pdf" withExtension:nil];

pdf = CGPDFDocumentCreateWithURL((__bridge CFURLRef)pdfURL); numberOfPages = CGPDFDocumentGetNumberOfPages(pdf);

myScrollview.contentSize = CGSizeMake( self.myScrollview.frame.size.width * numberOfPages, self.myScrollview.frame.size.height); myScrollview.pagingEnabled = YES;

20giovedì 24 maggio 12

Show me the code...

21giovedì 24 maggio 12

Gestire lo Zoom

• Scrollview con dentro Scrollviews :)

– Ogni pagina è una scrollview!

• Utilizzando per lo zoom il delegato:

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView

22giovedì 24 maggio 12

Zoom con doppio tap

• Intercettarlo tramite touchesBegan

• Permettere lo zoom in base a dove si è fatto il tap!

• Tornare a zoom scale = 1 con ulteriore doppio tap

23giovedì 24 maggio 12

Zoom con doppio tap- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{! CGPoint punto = [[touches anyObject] locationInView:self];! CGRect frameToZoom ; NSInteger radius = self.frame.size.width / 5; frameToZoom = CGRectMake(punto.x-radius, punto.y-radius, radius*2, radius*2); ! UITouch *touch = [touches anyObject];! if([touch tapCount] == 2) { if(self.zoomScale == 1.0) ! { ! ! [self zoomToRect:frameToZoom animated:YES]; } ! else ! { ! ! [self setZoomScale:1.0 animated:YES]; ! } }}

24giovedì 24 maggio 12

Show me the code...

25giovedì 24 maggio 12

il Pdf è vettoriale!!!

26giovedì 24 maggio 12

CATiledLayer• Presente dentro QuartzCore!

• Poca documentazione (4 properties, 1 Class Method)

• Esempio: Applicazione Mappe

• Ogni view possiede un CALayer

– CATiledLayer è una sottoclasse di CALayer!

• Per il disegno usare drawLayer:inContext:

27giovedì 24 maggio 12

LevelofDetail e LevelOfDetailBias• Level Of Detail il num di livelli di dettaglio per il layer

• Level Of Detail Bias è il num di livelli magnified di dettaglio per il layer

• Ogni LODB/LOD è una potenza di due o più rispetto al livello di dettaglio

28giovedì 24 maggio 12

TileSize

• E’ la grandezza massima di ogni singolo tile usato nel layer

• Di base è 256x256

• Ci sono problemi con iPad 3 :(

29giovedì 24 maggio 12

LevelofDetail e LevelOfDetailBias• UIScrollview con zoom

– minimumZoomScale 0.125f

– maximumZoomScale 8.0f

– Zoom di fattore 8

• Potremmo scegliere LevelOfDetail 7 e LevelOfDetailBias 3

– 7 configurazioni di level of detail

– ogni livello è la metà di risoluzione del precedente

– primi 3 sono a risoluzione “magnified”

– il 4 è a risoluzione normale

– gli ultimi 3 sono a risoluzione ridotta

30giovedì 24 maggio 12

31

Level 0 8192×8192

Level 1 4096×4096

Level 2 2048×2048

Level 3 1024×1024

Level 4 512×512

Level 5 256×256

Level 6 128×128

giovedì 24 maggio 12

CATiledLayer#import <QuartzCore/QuartzCore.h>

@implementation QuartzView

- (id)initWithFrame:(CGRect)frame andPdfPage:(CGPDFPageRef)page{ self = [super initWithFrame:frame]; if (self) { CATiledLayer *tiledLayer = (CATiledLayer *)[self layer]; tiledLayer.levelsOfDetail = 7;! ! tiledLayer.levelsOfDetailBias = 3;! ! tiledLayer.tileSize = CGSizeMake(512.0, 512.0);

pagina = page; pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); pdfScale = self.frame.size.width/pageRect.size.width; pageRect.size = CGSizeMake(pageRect.size.width*pdfScale, pageRect.size.height*pdfScale);

} return self;}

32giovedì 24 maggio 12

CATiledLayer+ (Class)layerClass {! return [CATiledLayer class];}

- (void)drawRect:(CGRect)rect{}

-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context{! CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0); CGContextFillRect(context,pageRect);!! CGContextSaveGState(context);! CGContextTranslateCTM(context, 0.0, pageRect.size.height);! CGContextScaleCTM(context, 1.0, -1.0);!! CGContextScaleCTM(context, pdfScale,pdfScale);!! CGContextDrawPDFPage(context, pagina);! CGContextRestoreGState(context);}

33giovedì 24 maggio 12

Show me the code...

34giovedì 24 maggio 12

Metadati• Dalle specifiche sono presenti al capitolo

10.2 Metadata• Sono in un formato “particolare”• Si possono estrarre con CoreGraphics 8-)

35

1 0 obj<< /Title ( PostScript Language Reference, Third Edition )

/Author (Adobe Systems Incorporated)/Creator (Adobe FrameMaker 5.5.3 for Power Macintosh®) /Producer (Acrobat Distiller 3.01 for Power Macintosh) /CreationDate (D:19970915110347-08'00')/ModDate (D:19990209153925-08'00')

>> endobj

giovedì 24 maggio 12

Metadati

36giovedì 24 maggio 12

Titolo ed autore del pdfCGPDFDictionaryRef info = CGPDFDocumentGetInfo(pdf);

CGPDFStringRef titleStringRef;CGPDFDictionaryGetString(info, "Title", &titleStringRef);const unsigned char *titleCstring = CGPDFStringGetBytePtr(titleStringRef);

printf("Titolo: %s", titleCstring);

CGPDFStringRef authorStringRef;CGPDFDictionaryGetString(info, "Author", &authorStringRef);const unsigned char *authorCstring = CGPDFStringGetBytePtr(authorStringRef);

printf("\nAutore: %s", authorCstring);

37giovedì 24 maggio 12

Accesso ai dati PDF• CGPDFDocument

• CGPDFDocumentGetCatalog

• CGPDFPage

• CGPDFPageGetDictionary

• CGPDFObjectGetObject, CGPDFDictionaryGetBoolean, CGPDFDictionaryGetInteger, CGPDFDictionaryGetString, CGPDFDictionaryGetArray...

38giovedì 24 maggio 12

Indice

• Non è sempre presente :)

• In base alla versione ed al formato potrebbe cambiare... (gestire più casi!)

• Dalle specifiche presente nel capitolo

8.2 Document-Level Navigation

39giovedì 24 maggio 12

Outline Document

40giovedì 24 maggio 12

Outline Item• Chiavi:

– Title– Parent / Prev / Next

– First / Last

– Count– Dest / A / SE

41

CGPDFDictionaryRef dict = CGPDFDocumentGetCatalog(pdf);

CGPDFDictionaryRef ret; if( (CGPDFDictionaryGetDictionary(dict, "Outline", &ret)) || (CGPDFDictionaryGetDictionary(dict, "Outlines", &ret)))

{

}

giovedì 24 maggio 12

Show me the code...

42giovedì 24 maggio 12

Altre possibilità... che non vedremo :)

• Links• Annotations (cap. 8.4)• Thumbnail (cap 8.2.3)• Ricerca testuale (estrazione full text)

43giovedì 24 maggio 12