In some apps there might come a time where you will need to generate your own documents on the fly and be able to export them to the user, either to preview, email or to save the document on the device for later use.

The UIKit framework in iOS provides a easy way to create a graphics context which allows you to generate a PDF file or PDF data object. You should then be able to create extra pages and draw them into the pdf context. Here is how you can start creating your own PDF document.

Setup of PDF Context

So what we first do is setup file name for the file.

NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString *pdfFileName = [documentDirectory stringByAppendingPathComponent:@"mypdf.pdf"];

Once that is done, we can start the graphics context to file and return the context reference so that we can render to it.

UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);
CGContextRef context = UIGraphicsGetCurrentContext();

Before we can start drawing anything, we need to mark the beginning of a new page. When you are finished drawing on a page and need to start a new page, just call the same line and reset your offset back to 0 again.

UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);

If you are going to generate data that could possibly go over multiple pages, I would recommend to setup a pageOffset before creating a page. You can use this to calculate if you have reached the end of a page, so that you can create a new PDF page context.

CGFloat pageOffset = 0;

Drawing to the PDF Page.

Drawing objects to a PDF page is easy, below are some examples of what you can draw.

Text

NSString *myString = @"My PDF Heading";
[myString drawInRect:CGRectMake(20, pageOffset, 200, 34) withFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:13] lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft];

Image

UIImage *myImage = [UIImage imageNamed:@"logo.png"];
[myImage drawInRect:CGRectMake(20, pageOffset, myImage.size.width, myImage.size.height)];

Link
Besides drawing graphics content, you can also setup a link which can direct a user to another page in the PDF or to an external file or URL.

To create a simple link, you will need to setup a link and a destination. Below we setup firstly a destination, then a link which goes back to that destination inside the current PDF file.

UIGraphicsAddPDFContextDestinationAtPoint(@"Chapter1", CGPointMake(0, 0));
UIGraphicsSetPDFContextDestinationForRect(@"Chapter1", CGRectMake(50, 50, 200, 44));

If you would like to create a link to an external URL, you can use the following.

UIGraphicsSetPDFContextURLForRect(<#NSURL *url#>, <#CGRect rect#>);

Finishing the PDF and exporting the data
Once you have finished creating your PDF you must first remove the PDF rendering context.

UIGraphicsEndPDFContext();

Now you have access to use the PDF and export it how you wish. To access the file to attach it in the MFMailComposeViewController, you can do the following.

[mailComposer addAttachmentData:[NSData dataWithContentsOfFile:pdfFileName] mimeType:@"application/pdf" fileName:@"myGeneratedPDF.pdf"];

If you would like to know more about PDF rendering, you can refer to the Apple docs on
Generating PDF Content.