(i) External way - the PDF document can be created with the help of a server. In this case, the app simply send the data (suitably structured) to a server which generates the PDF file using some server side script. Once the file is generated, it can be sent back to the app for further actions, such as forwarding it via email to someone. Indeed, the server could send the file directly to whomever.
(ii) Internal way - the PDF document is generated within the app on the iPhone or iPad (without involving an external server).
Which way is better depends on your requirements. The involvement of a server is sometimes necessary if you need to combine external data to create the PDF document. An external server may be more efficient if the document is complex or large.
This note is about the internal way.
Generating PDF directly on the iPhone and iPad
PDF document can be created in iOS. The Quartz 2D drawing engine is developed with PDF document creation, display and parsing in mind. The process of creating a PDF document is perhaps not as obvious as other things in iOS, but it is certainly not difficult and you can create nice looking document just by knowing a few things.
There are two ways to generate a PDF document on iOS:
(i) Use Core Graphics functions; and
(ii) Use UIKit framework.
The UIKit framework is certainly much easier to use that calling Core Graphics functions, but the latter could be more flexible and powerful. Again, the better approach depends on your requirements and it can be matter of personal taste.
This is an excellent online tutorial: Generate PDF programmatically in iPhone/iPad SDK. It shows you how to draw lines, border, text and image.
For those who like to write even less code and leverage the graphical user interface of Interface Builder, you can use UILabel to display text on the PDF document. Here is how.
A Simple Example
This example creates a landscape page with an image on the left and some text on the right hand side.
1. Create a UILabel object in Interface Builder. i.e. simply drag a UILabel object onto the view controller in Interface Builder.
2. Create the setter and getter for this label in the class files of the view controller using the standard @property and @synthesize technique, i.e.
@property (strong, nonatomic) IBOutlet UILabel *textLabel;
@synthesize textLabel = _textLabel;
(Remember to connect this to the actual UILabel in Interface Builder. As an aside, it is quite easy to forget to do this, at least I often do. This is why I prefer to let xCode creates the @property and @syntheize code automatically by using the 'control click and point' technique. Another advantage of this approach is that xCode will add the relevant memory management code automatically too - one less thing to do).
3. Enter the following codes in viewDidLoad:
// defines the path for the saved pdf file
NSString *docDirectory =
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *pdfPath = [docDirectory stringByAppendingPathComponent:@"pdfFile.pdf"];
// set the size of the page (the page is in landscape format)
CGRect pageBounds = CGRectMake(0.0f, 0.0f, 792.0f, 612.0f);
// sets the size and position of the image and text
CGRect imageBounds = CGRectMake(30.0f, 50.0f, 500.0f, 375.0f);
CGRect textBounds = CGRectMake(550.0f, 50.0f, 182.0f, 375.0f);
// create an UIImage object using a photo named "sampleImage.jpg"
UIImage *theImage = [UIImage imageNamed:@"sampleImage.jpg"];
// set the text
_textLabel.text = @"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.";
// create and save the pdf file
UIGraphicsBeginPDFContextToFile(pdfPath, pageBounds, nil);
{
UIGraphicsBeginPDFPage();
[theImage drawInRect:imageBounds];
[_textLabel drawTextInRect:textBounds];
}
UIGraphicsEndPDFContext();
4. One final step. Select the UILabel in Interface Builder, and in the Attribute Inspector, make sure that the attributes are set with the following values:
Lines: 0 (setting to zero means that it is unbounded)
Line Breaks: Character Wrap
Font: System 14.0 (you can use other size or font)
Text Color: (use default or pick a color)
Run the code in the Simulator and the PDF file will be saved inside the app's Documents folder. You can then add code to email or do whatever you want with the PDF file.
Drawing an NSString directly to the pdf context is more flexible, but an advantage of using UILabel as describe here is that it allows you to change the font, size, style, color, etc graphically in Interface Builder. This can be quite useful when you want to knock up something fast. Doing similar using NSString requires more coding and, as far as I know, you cannot simple things like 'bolding' the text without using Core Text and NSAttributedString (which is not that friendly to use). Again, the better approach to use depend on your requirement.