I want to have my iPhone application create a PDF file and store it in an appropriate place - probably the iBooks folder so it can be easily retrieved using iTunes, but that's a change for later once I have the saving part working. I've followed the PDF saving tutorial on the Apple site to the letter, including swapping out CGContextBeginPage and CGContextEndPage for their PDF specific equivalents, and I've checked that the save filename is set to the correct spot, but either no file is being created or I just can't find where it's being stored. Here's the code, any ideas what's wrong? Is it the code, or does this kind of operation just not run in the simulator?
CGRect b = CGRectMake(0, 0, 612, 792);
NSMutableString *exportPath = [[NSMutableString alloc]
initWithString:[[NSBundle mainBundle] bundlePath]];
[exportPath appendString:#"/myfile.pdf"];
CGContextRef pdfContext;
CFStringRef path = CFStringCreateWithCString (NULL, [exportPath UTF8String], kCFStringEncodingUTF8);
CFURLRef url; CFMutableDictionaryRef myDictionary = NULL;
url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, 0);
CFRelease(path);
myDictionary = CFDictionaryCreateMutable(NULL, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("My PDF File"));
CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("My Name"));
pdfContext = CGPDFContextCreateWithURL (url, &b, myDictionary);
CFRelease(myDictionary);
CFRelease(url);
CGPDFContextBeginPage(pdfContext, NULL);
[self drawToContext: pdfContext Bounds:b];
CGPDFContextEndPage(pdfContext);
CGPDFContextClose(pdfContext);
CGContextRelease (pdfContext);
You are trying to save the PDF into your bundle. I'm pretty sure you can do that. Use the document path instead.
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString *dbpath = [documentsDir stringByAppendingPathComponent:#"myfile.pdf"];
Related
Hi Friends I am Trying to create annotation of PDF page as something like bellow image in my app and this annotation is visible to all other PDF reader
For example:-
I create PDF document in My app and Add Annotation then i send this Document to My Friend Mail. Then my Friend Download this PDF and Open in to Preview App of Mac then this created Annotation of PDF that should be display.`
I doing RND of This stuff and Also Read iOS provide Doc about Quartz 2D. I successful read and create PDF using this Quartz 2D but now not getting any way to doing Annotation stuff.
I also study those kind of SO questions:-
Create PDF Annotations in iOS
Create PDF Annotations with Quartz (iOS)
pdf annotations in objective-c
I also done Annotation withing the App Reading PDF and store Point of x and y potion of Layer drage in to particular PDF page. Now issue is that what about when i send this PDF document to other user who open this Document in others PDF reader?
I also Discuss this SO chat Group. one of Stack-overflow User suggest me to Using CGLayer for doing this task But i am much Confused how to achieve this stuff and how to implement this.
Please Help me and Guide Me on this stuff.
The answer is simply no, you cannot create standard PDF annotations using the iOS APIs. The CGPDF* API is read-only and it can be used only to read PDF file and the CoreGraphics API with PDF context can only create simple PDF pages without annotations, form fields, bookmarks, etc.
If you create new PDF files you can switch to libHaru which supports annotations but if want to add annotations to existing PDF files you're out of luck (libHaru cannot load PDF files). There is also IFXPDFFactory but it is under development and I do not know if it supports annotations yet.
First I don't know is it only because of complexity that people suggest the costly PDF iOS libraries out there or they are promoting them by commenting that this and that cannot be done without prior testing.
You can add and save annotations in the pdf file and even export it.
NSURL *OriginalPdfPath = [[NSBundle mainBundle] URLForResource:#"yourPDFname" withExtension:#"pdf"];
NSString *string=[OriginalPdfPath path];
NSError *error;
//Load original pdf data:
NSData *pdfData = [NSData dataWithContentsOfFile:string options:NSDataReadingUncached error:&error];
if (error)
{
NSLog(#"%#", [error localizedDescription]);
return;
}
else {
NSLog(#"Data has loaded successfully.");
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathLD = [documentsDirectory stringByAppendingPathComponent:#"dirName"]; // get directory
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:pathLD])
{
[fileManager createDirectoryAtPath:pathLD withIntermediateDirectories:YES attributes:nil error:nil];
}
pathLD = [pathLD stringByAppendingPathComponent:#"yourPDFname.pdf"]; // add file path
BOOL isDir;
if (![fileManager fileExistsAtPath:pathLD isDirectory:&isDir]) {
BOOL didsave=[fileManager createFileAtPath:pathLD contents:pdfData attributes:nil];
}
NSURL *url = [NSURL fileURLWithPath:string];
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL ((__bridge_retained CFURLRef) url);
size_t count = CGPDFDocumentGetNumberOfPages(document);
if (count == 0)
{
NSLog(#"PDF needs at least one page");
return;
}
// Now work with the pdf File
UIGraphicsBeginPDFContextToFile(pathLD , CGRectZero, nil);
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGPDFPageRef page = CGPDFDocumentGetPage (document, 1);
CGRect paperSize = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox);
UIGraphicsBeginPDFContextToFile(pathLD , CGRectZero, nil);
UIGraphicsBeginPDFPageWithInfo(paperSize, nil);
// Flip the context so that the PDF page is rendered right side up.
CGContextTranslateCTM(currentContext, 0.0, paperSize.size.height);
CGContextScaleCTM(currentContext, 1.0, -1.0);
CGContextDrawPDFPage (currentContext, page);
// Magic function here : Render the layer of the annotations view in the context
[drawingView.layer renderInContext:currentContext];
UIGraphicsEndPDFContext();
CGPDFDocumentRelease (document);
This saves all that you render in current pdf context back to the File Manager
you can test that with a model View display VC on a WebView:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self displayPdfinWebView];
}
-(void)displayPdfinWebView {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory =[paths objectAtIndex:0];
NSString *pathLD = [documentsDirectory stringByAppendingPathComponent:#"dirName"]; // get directory
pathLD = [pathLD stringByAppendingPathComponent:#"yourPDFname.pdf"]; // add file path
NSFileManager *fileManager = [NSFileManager defaultManager];
NSData *data;
NSURL* pdfUrl;
if ([fileManager fileExistsAtPath:pathLD])
{
pdfUrl = [NSURL fileURLWithPath:pathLD];
[webView loadRequest:[NSURLRequest requestWithURL:pdfUrl]];
}
}
I guess you can connect to iBooks with UIDocumentInteractionController for exporting.
My references is ApplePDF Drawing .
How might one convert a screenshot, taken on an iPhone for example, into a PDF file. It's easy enough to take the screenshot and put it into a UIImage, but it's the conversion which has me stumped. I took a look at the Quartz framework which is the only one in Xcode that I know to support the PDF format, but couldn't find anything there to make this work. Is there anything native to Xcode that I'm missing? If not, is there a public framework somewhere that could handle a conversion like this?
I figured it out. It involved saving a screenshot as a UIImage, and then using the very helpful tutorial found here to get me going with the PDF conversion. As it turns out, there are functions to handle the making of PDF documents in the Core Graphics class.
You wouldn't convert a screenshot to a pdf. You would create a screenshot, create a pdf and insert the screenshot image into the first page of the pdf.
Untested code to create image:
nameStr = [NSString stringWithFormat:#"myImage.png"];
fileManager = [NSFileManager defaultManager];
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
namePath = [documentsDirectory stringByAppendingString:#"/"];
namePath = [thumbnailPath nameStr];
CGRect contextRect = CGRectMake(0, 0, 1024, 768);
UIGraphicsBeginImageContext(contextRect.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *data = UIImagePNGRepresentation(viewImage);
UIImage *myImage = [[UIImage alloc] initWithData:data];
Untested code to add image to a pdf:
pageSize = CGSizeMake(1024, 768);
fileName = #"myFile.pdf";
pdfFileName = [documentsDirectory stringByAppendingPathComponent:fileName];
UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
[myImage drawInRect:CGRectMake( 0, 0, 1024, 768];
UIGraphicsEndPDFContext();
p.s. assuming ipad 1024 x 768 above
Per these guidelines, I'm creating a CAF file containing PCM data. The location is in the application's documents directory, and the file seems to be there (per Xcode Organizer). This is how I determine the path to write out to:
// setup our file write area
//
NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
NSString *exportPath = [[documentsDirectoryPath stringByAppendingPathComponent:#"exported.caf"] retain];
NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
Now, I'm trying to read the file thusly:
CFStringRef aCFString = (CFStringRef) [exportURL absoluteString];
CFURLRef sndFile = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, aCFString, kCFURLPOSIXPathStyle, false);
OSStatus result = AudioFileOpenURL(sndFile, kAudioFileReadPermission, kAudioFileCAFType, &fileID);
However, the result from this operation is -43, which per MacErrors.h is a file not found. I initially thought it could be a variant of this question:
AudioFileOpenURL returns -43 on an existing file
But now I don't think so. The file handles that created the PCM should be closed. Anyone have any ideas? Am I doing something really stupid here?
Thank you for your time :)
I'm Using Leaves project to show my PDFs in my iphone project but i have a problem when i'm trying to display the pdf from the document not from bundle .. i think it's simple but have a trick i can't get cause i'm not guru in pdf reading :)
i'm using the following code
-(void) viewWillAppear:(BOOL)animated{
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentPaths objectAtIndex:0];
pListPath = [ documentDir stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",self.fileName]];
CFURLRef pdfURL = (CFURLRef)[NSURL fileURLWithPath:pListPath];
// CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("fekhElSunaI.pdf"), NULL, NULL);
pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
NSLog(#"%#",pListPath);
// CFRelease(pdfURL);
[self init];
}
you'll notice that i've put the code in the viewWillAppear not in the init as leaves do ..
the pdf is not appear and not initialized
i've used the solution that is on this LINK and it didn't work either
so any one here have something to help me with :)
You've put the code in viewWillAppear, and that's probably your issue. Elsewhere the code might assume the code is already called, and the PDF already there. Try putting it in init, and see what happens. viewWillAppear might get called several times.
Use this code
- (id)init {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
myPathDocs = [documentsDirectory stringByAppendingPathComponent:#"abc.pdf"];
pdfURL = (CFURLRef)[NSURL fileURLWithPath:myPathDocs];
NSLog(#"myString %#",myPathDocs);
pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL); // }
size_t pageCount = CGPDFDocumentGetNumberOfPages(pdf);
}
for your Leavies View init function
I am creating an app that needs access to the documents directory. I am currently using the following to return the URL of a file pdfName from the main bundle. Is there a similar way of getting the documents directory?
CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), (CFStringRef)pdfName, NULL, NULL);
Edit: this is my full code, but it isn't working - any ideas?
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *myFilePath = [documentsDirectory stringByAppendingPathComponent:pdfName];
CFURLRef pdfURL = (CFURLRef)[NSURL fileURLWithPath:myFilePath];
pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
CFRelease(pdfURL);
I had the same problem. The app crashed when creating the CFURLRef. This is how i solved it (given you already have an NSString with the complete path to the file in documents directory):
CFURLRef pdfURL = (__bridge CFURLRef)[[NSURL alloc] initFileURLWithPath:myFilePath];
pdf = CGPDFDocumentCreateWithURL(pdfURL);
CFRelease(pdfURL);
Looks like the only difference in my code is that I alloc and init the NSURL.
This might help you: ADC Link