CGPDFDictionaryRef for something useful

A bit of background: I am adding an image to an existing PDF file. I found out that there is no way to just add a page to it, you have to recreate the entire PDF, and then delete the old one, and then move the new one. (If this is not correct, please tell me, and this will save me many headaches.) I have completed this part, but now I am trying to copy additional information (Title, Author, Keys, etc.). The problem is that there are so many types of problems that the current method I use is to get CGPDFDocumentRef CGPDFDictionaryRef and then call CGPDFDictionaryApplierFunction. In the C function, I pass it, I retrieve each key in an NSMutableDictionary so that I can then do something with the values ​​and not block them in this terrible CGPDF format.

So basically my question is: Is there a better way to do this? I stared at a lot of documentation files that I could not imagine without losing anything, but I really hope that I have, because the number of workarounds I need to make becomes absurd.

+7
dictionary iphone pdf
source share
2 answers

I completed my workaround. I would still like to know if there is a better way to do this, so if you know one or have any suggestions, I am ready to try them out.

Notes. I check only for bools, ints, strings and arrays, because according to Apple's documentation, this is all that should be in the additional information in the PDF. The array bit is not checked because I do not have a PDF file with the array in Aux Info. If someone wants to check it out for me or a link to a pdf with one in it, I will be happy to check it out.

First, in the class header, create an id selfClass outside the id selfClass tags @interface that the C functions called by CGPDFDictionaryApplyFunction can access the current class. Also add NSDictionary *auxInfo to store information. After extraction, the type NS can be easily done as follows:

 CFDictionaryRef newDictionary = (CFDictionaryRef)[self auxInfo]; 

I really was done last night, but thought I needed to do another round of the cycle to convert from NS to CF, forgetting that they were fraudulent. So, you have it, I hope that everyone will benefit from my work. Ask questions if you need clarification. And again, if there is an easier way to do this, if only optimizing my code, say so. I know this is not a very elegant way to do this, but it works now.

 - (void)extractPDFDictionary:(CGPDFDocumentRef)pdf{ NSLog(@"extractingPDFDictionary"); CGPDFDictionaryRef oldDict = CGPDFDocumentGetInfo(pdf); CGPDFDictionaryApplyFunction(oldDict, copyDictionaryValues, NULL); } void copyDictionaryValues (const char *key, CGPDFObjectRef object, void *info) { NSLog(@"key: %s", key); CGPDFObjectType type = CGPDFObjectGetType(object); switch (type) { case kCGPDFObjectTypeString: { CGPDFStringRef objectString; if (CGPDFObjectGetValue(object, kCGPDFObjectTypeString, &objectString)) { NSString *tempStr = (NSString *)CGPDFStringCopyTextString(objectString); [[selfClass auxInfo] setObject:tempStr forKey:[NSString stringWithCString:key encoding:NSUTF8StringEncoding]]; [tempStr release]; NSLog(@"set string value"); } } case kCGPDFObjectTypeInteger: { CGPDFInteger objectInteger; if (CGPDFObjectGetValue(object, kCGPDFObjectTypeInteger, &objectInteger)) { [[selfClass auxInfo] setObject:[NSNumber numberWithInt:objectInteger] forKey:[NSString stringWithCString:key encoding:NSUTF8StringEncoding]]; NSLog(@"set int value"); } } case kCGPDFObjectTypeBoolean: { CGPDFBoolean objectBool; if (CGPDFObjectGetValue(object, kCGPDFObjectTypeBoolean, &objectBool)) { [[selfClass auxInfo] setObject:[NSNumber numberWithBool:objectBool] forKey:[NSString stringWithCString:key encoding:NSUTF8StringEncoding]]; NSLog(@"set boolean value"); } } case kCGPDFObjectTypeArray : { CGPDFArrayRef objectArray; if (CGPDFObjectGetValue(object, kCGPDFObjectTypeArray, &objectArray)) { NSArray *tempArr = [selfClass copyPDFArray:objectArray]; [[selfClass auxInfo] setObject:tempArr forKey:[NSString stringWithCString:key encoding:NSUTF8StringEncoding]]; [tempArr release]; NSLog(@"set array value"); } } } } - (NSArray *)copyPDFArray:(CGPDFArrayRef)arr{ int i = 0; NSMutableArray *temp = [[NSMutableArray alloc] init]; for(i=0; i<CGPDFArrayGetCount(arr); i++){ CGPDFObjectRef object; CGPDFArrayGetObject(arr, i, &object); CGPDFObjectType type = CGPDFObjectGetType(object); switch(type){ case kCGPDFObjectTypeString: { CGPDFStringRef objectString; if (CGPDFObjectGetValue(object, kCGPDFObjectTypeString, &objectString)) { NSString *tempStr = (NSString *)CGPDFStringCopyTextString(objectString); [temp addObject:tempStr]; [tempStr release]; } } case kCGPDFObjectTypeInteger: { CGPDFInteger objectInteger; if (CGPDFObjectGetValue(object, kCGPDFObjectTypeInteger, &objectInteger)) { [temp addObject:[NSNumber numberWithInt:objectInteger]]; } } case kCGPDFObjectTypeBoolean: { CGPDFBoolean objectBool; if (CGPDFObjectGetValue(object, kCGPDFObjectTypeBoolean, &objectBool)) { [temp addObject:[NSNumber numberWithBool:objectBool]]; } } case kCGPDFObjectTypeArray : { CGPDFArrayRef objectArray; if (CGPDFObjectGetValue(object, kCGPDFObjectTypeArray, &objectArray)) { NSArray *tempArr = [selfClass copyPDFArray:objectArray]; [temp addObject:tempArr]; [tempArr release]; } } } } return temp; } 
+10
source share

You can accomplish what you describe using CGPDFContext , but if you have a complex PDF file, you can try something other than what the API was intended for. You can take a look at section 3.4 of the PDF specification and see what you get.

0
source share

All Articles