Gestire i pdf con iOS

44
Maurizio Moriconi - @bugman79 Mobilesoft Gestire i PDF con iOS

Transcript of Gestire i pdf con iOS

Page 1: Gestire i pdf con iOS

Maurizio Moriconi - @bugman79Mobilesoft

Gestire i PDF con iOS

Page 2: Gestire i pdf con iOS

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

Page 3: Gestire i pdf con iOS

Editoria digitale

3

Page 4: Gestire i pdf con iOS

4

Page 5: Gestire i pdf con iOS

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

5

Page 6: Gestire i pdf con iOS

Editoria su iOS

• Varie possibilità:

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

– HTML 5

6

Page 7: Gestire i pdf con iOS

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...)

7

Page 8: Gestire i pdf con iOS

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

8

Page 9: Gestire i pdf con iOS

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

pdf_reference.html

9

Ultima versione:

PDF Reference, sixth edition APDF version 1.7

1310 pagine!!!

Page 10: Gestire i pdf con iOS

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

10

Page 11: Gestire i pdf con iOS

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];

11

Page 12: Gestire i pdf con iOS

Show me the code...

12

Page 13: Gestire i pdf con iOS

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

13

Page 14: Gestire i pdf con iOS

Classi che ci interessano

• CGPDFDocument• CGPDFPage• CGPDFObject

• CGContext

14

Page 15: Gestire i pdf con iOS

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);

15

Page 16: Gestire i pdf con iOS

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);

16

Page 17: Gestire i pdf con iOS

Show me the code...

17

Page 18: Gestire i pdf con iOS

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

18

Page 19: Gestire i pdf con iOS

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);}

19

Page 20: Gestire i pdf con iOS

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;

20

Page 21: Gestire i pdf con iOS

Show me the code...

21

Page 22: Gestire i pdf con iOS

Gestire lo Zoom

• Scrollview con dentro Scrollviews :)

– Ogni pagina è una scrollview!

• Utilizzando per lo zoom il delegato:

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

22

Page 23: Gestire i pdf con iOS

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

23

Page 24: Gestire i pdf con iOS

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]; ! } }}

24

Page 25: Gestire i pdf con iOS

Show me the code...

25

Page 26: Gestire i pdf con iOS

il Pdf è vettoriale!!!

26

Page 27: Gestire i pdf con iOS

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:

27

Page 28: Gestire i pdf con iOS

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

28

Page 29: Gestire i pdf con iOS

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

28

Page 30: Gestire i pdf con iOS

TileSize

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

• Di base è 256x256

• Ci sono problemi con iPad 3 :(

29

Page 31: Gestire i pdf con iOS

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

30

Page 32: Gestire i pdf con iOS

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

Page 33: Gestire i pdf con iOS

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;}

32

Page 34: Gestire i pdf con iOS

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);}

33

Page 35: Gestire i pdf con iOS

Show me the code...

34

Page 36: Gestire i pdf con iOS

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

Page 37: Gestire i pdf con iOS

Metadati

36

Page 38: Gestire i pdf con iOS

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);

37

Page 39: Gestire i pdf con iOS

Accesso ai dati PDF• CGPDFDocument

• CGPDFDocumentGetCatalog

• CGPDFPage

• CGPDFPageGetDictionary

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

38

Page 40: Gestire i pdf con iOS

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

39

Page 41: Gestire i pdf con iOS

Outline Document

40

Page 42: Gestire i pdf con iOS

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)))

{

}

Page 43: Gestire i pdf con iOS

Show me the code...

42

Page 44: Gestire i pdf con iOS

Altre possibilità... che non vedremo :)

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

43