2010-09-29 4 views
5

Bei der Arbeit an einer Feed-Lesung iPhone-App, die Nsdata (HTML und PDF) in einem UIWebView anzeigt. Ich stoße in einer PDF-Validierungslogik auf einen Haken. Ich habe ein NSData-Objekt, von dem ich weiß, dass es eine Datei mit der Erweiterung .pdf enthält. Ich möchte ungültige PDFs davon abhalten, weiter zu kommen. Hier ist mein erster Versuch Validierungscode, die für eine Mehrzahl der Fälle scheint zu funktionieren:Wie validiere ich, dass eine NSData eine PDF ist?

// pdfData is an NSData * 
NSData *validPDF = [[NSString stringWithString:@"%PDF"] dataUsingEncoding: NSASCIIStringEncoding]; 
if (!(pdfData && [[pdfData subdataWithRange:NSMakeRange(0, 4)] isEqualToData:validPDF])) { 
    // error 
} 

Leider ein neues pdf vor ein paar Tagen hochgeladen wurde. Es ist in dem Sinne gültig, dass das UIWebView es gut anzeigt, aber es schlägt meinen Validierungstest fehl. Ich habe das Problem auf die Tatsache aufgespürt, dass es am Anfang eine Menge von Müll-Bytes war, wobei die% PDF Mitte durch den 14. Satz von Hex-Zeichen kam (die 25 oder% ist genau das 54. Byte):

%PDF: 25504446 
Breaking PDF: 00010000 00ffffff ff010000 00000000 000f0100 0000b5e0 04000200 01000000 ffffffff 01000000 00000000 0f010000 0099e004 00022550 44462d31 etc... 

Was ist die beste Vorgehensweise für die Validierung von NSData als PDF?
Was könnte mit dieser bestimmten PDF-Datei falsch sein (sie behauptet, sie sei von PaperPort 11.0 codiert, was auch immer das ist)?

Danke,

Mike

+0

es gibt nichts in ImageIO, die dabei helfen können? – nielsbot

Antwort

4

Diese Frage scheint sehr hilfreich:

Detect if PDF file is correct (header PDF)

oder, wenn Sie etwas Zeit mitbringen, here's the spec (von der Adobe-Website here)

+0

Ja, danke für die Verlinkung. Es nervt, dass um den Header etwas Unschärfe ist. Also suche ich nur die ersten 1024 Bytes der NSData nach% PDF, 4 Bytes gleichzeitig, oder gibt es einen Weg, einen Datenblock nach einer Zeichenkette zu durchsuchen? – TahoeWolverine

+0

Sie könnten die ersten 1024 Zeichen in einen NSString umwandeln (mit _subdatawithRange: _ von NSData, um die ersten 1024 Bytes zu erhalten, und dann mit der _initWithData: encoding: _ -Methode von NSString in ein NSString-Objekt) und mit rangeOfString: to suchen sehen, ob es da drin ist? – deanWombourne

+0

NB Stellen Sie sicher, Sie haben> = 1024 Bytes oder mindestens eine dieser Methoden wird eine Ausnahme auslösen;) – deanWombourne

2

In Swift habe ich folgendes:

var isPDF:Bool = false 
if assetData.length >= 1024 //only check if bigger 
{ 
    var pdfBytes = [UInt8]() 
    pdfBytes = [ 0x25, 0x50, 0x44, 0x46] 
    let pdfHeader = NSData(bytes: pdfBytes, length: 4) 
    let foundRange = assetData.rangeOfData(pdfHeader, options: nil, range: NSMakeRange(0, 1024)) 
    if foundRange.length > 0 
    { 
     isPDF = true 
    } 
} 
2

kann dies versuchen ..

// Validate PDF using NSData 
    - (BOOL)isValidePDF:(NSData *)pdfData { 
     BOOL isPDF = false; 
     if (pdfData.length >= 1024) { 

      int startMetaCount = 4, endMetaCount = 5; 
      // check pdf data is the NSData with embedded %PDF & %%EOF 
      NSData *startPDFData = [NSData dataWithBytes:"%PDF" length:startMetaCount]; 
      NSData *endPDFData = [NSData dataWithBytes:"%%EOF" length:endMetaCount]; 
      // startPDFData, endPDFData data are the NSData with embedded in pdfData 
      NSRange startRange = [pdfData rangeOfData:startPDFData options:0 range:NSMakeRange(0, 1024)]; 
      NSRange endRange = [pdfData rangeOfData:endPDFData options:0 range:NSMakeRange(0, pdfData.length)]; 

      if (startRange.location != NSNotFound && startRange.length == startMetaCount && endRange.location != NSNotFound && endRange.length == endMetaCount) { 
       // This assumes the start & end PDFData doesn't have a specific range in file pdf data 
       isPDF = true; 

      } else { 
       isPDF = false; 
      } 
     } 
     return isPDF; 
    } 
+0

Müssen Sie wirklich 'malloc()' 4 Bytes? Übrigens können Sie einfach "% PDF" statt "pdfBytes" verwenden. – trojanfoe

+0

NSData * tempData = [NSData dataWithBytesNoCopy: pdfBytes Länge: 4 freeWhenDone: YES]; Ich habe kostenlos benutzt, wenn es wahr ist. Also müssen wir malloc() verwenden. –

+0

Nein, tust du nicht. Verwenden Sie stattdessen "[NSData dataWithBytes:"% PDF "length: 4]". – trojanfoe

3
let fileManager = FileManager() 
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] 
    let rootDirectory = "\(documentsPath)/\(caption!)/" 
    let imageURL = URL(fileURLWithPath: rootDirectory).appendingPathComponent("0") 
    let ns = NSData(contentsOf: imageURL) 
    let fileExists = fileManager.fileExists(atPath: imageURL.path) 
    var isPDF:Bool = false 
    if (ns?.length)! >= 1024 //only check if bigger 
    { 
     var pdfBytes = [UInt8]() 
     pdfBytes = [ 0x25, 0x50, 0x44, 0x46] 
     let pdfHeader = NSData(bytes: pdfBytes, length: 4) 
     let a = ns?.range(of: pdfHeader as Data, options: .anchored, in: NSMakeRange(0, 1024)) 
     if (a?.length)! > 0 
     { 
      isPDF = true 


     } 
     else 
     { 
      isPDF = false 

     } 
    } 
+0

Sie, mein Herr, sind ein Lebensretter – Malik

+0

Mein Vergnügen Herr malik –

Verwandte Themen