Reading & Displaying PDF Documents

Reading & Displaying PDF Documents

Tutorial Details
  • Technology: iOS SDK
  • Difficulty: Intermediate
  • Completion Time: 30 - 60 Minutes

Working with raw PDF documents can be a time consuming and frustrating task. This tutorial will teach you how to use the VFR Library to quickly access, display, and browse PDF documents within your own applications!

Introduction

There are many scenarios where it may become necessary to display a PDF in an iOS App. In doing so, there can be many complications in getting PDFs to render correctly. There are also additional features such as printing, e-mailing, viewing bookmarks, handling rotation, and more that should be accounted for. While many of these features may not be complicated to include, some can be very tricky to get working correctly.

PDF Viewer Final Product

Step 1: Install The VFR Library

For this app, we’ll start out by creating a new Xcode project as a “Single-View Application”. Also, we’ll be using ARC, so make sure that “Use Automatic Reference Counting” is checked.

New Project

Required Frameworks

Our PDF “Reader” library requires a few additional frameworks to be added to our project: QuartzCore, ImageIO, and MessageUI.

If you’re already familiar with adding frameworks to a project, then you can skip this next part and get right into “Adding the Library to Our Project”.

Otherwise, to add those frameworks, click on your Project from the Project Navigator. Choose your target, then find the “Build Phases” tab at the top. Underneath “Build Phases”, expand the “Link Binary With Libraries” section and then click the “+” button in the lower left-hand corner.

Required Frameworks

Now, add the required frameworks (QuartzCore, ImageIO, MessageUI).

Add Required Frameworks

Your “Link Binary With Options” section should now look like this:

Required Frameworks Have Been Added

Adding the Library to Our Project

Our PDF “Reader” library can be downloaded from GitHub here: https://github.com/vfr/Reader. We can now drag our “Reader” library into our project and we’re almost ready to start. I’ve created a new Group in my project called “PDF Reader” where I’m adding the library (you only need to include the “Sources” and “Graphics” directories).

Add the 'Reader' Library

Unfortunately, at this point, “Reader” is not ARC-ready. So, we’ll have to do some refactoring. There are three (3) files that we’ll need to manually update before we can tell Xcode to refactor for ARC: “ReaderDocument.m”, “ReaderContentPage.m”, and “ReaderThumbFetch.m” (for reference, you can find basic instructions for these files here: http://www.vfr.org/2012/05/reader-arc-conversion/.)

Basically, what we’re going to do is edit each of these files to use plain __bridge casts, like so:

ReaderDocument.m:

Change

... = [NSString stringWithString:(id)theString];

to
…

= [NSString stringWithString:(__bridge id)theString];

ReaderContentPage.m:

Change

... = CGPDFDocumentCreateX((CFURLRef)fileURL, phrase);

to…

... = CGPDFDocumentCreateX((__bridge CFURLRef)fileURL, phrase);

ReaderThumbFetch.m:

Change


... = CGImageSourceCreateWithURL((CFURLRef)thumbURL,

to…

... = CGImageSourceCreateWithURL((__bridge CFURLRef)thumbURL, NULL);

With the above changes made, go to Edit > Refactor > Convert to Objective-C ARC…

Refactor for ARC

You will be prompted to “Select Targets to Convert.” Make sure that your current target is selected, then press “Check”.

Check Target for Refactoring

The prompt will guide you through the process, you should be able to just hit “Next” without issue.

Refactor 'Next' Step

Then you’ll be able to “Review Changes”, and you can select “Save”.

Refactor 'Save'

Finally, we need to include our “Reader” library header into our main ViewController.h and set our main view controller as a ReaderViewControllerDelegate:

#import "ReaderViewController.h"

@interface MTViewController : UIViewController <ReaderViewControllerDelegate>

Step 2: Setup

The complicated part of our project setup is over. From this point, it’s quick work to start viewing PDFs in our apps -complete with printing, bookmarks, thumbnails, email, and more!

First thing, let’s add a demo PDF to our project. Once again, I’ve created a new group, this one I’ve called “PDFs”.

I’ve then added a PDF named “typo_tips.pdf” that I downloaded from fontshop.com in the “resources directory” that you can use (direct link). Of course, feel free to try any PDF that you already have as well.

Add Our PDF

To open our PDF, we’ll add a single UIButton in our main ViewController.xib.

Add Our UIButton

We’ll then hook up our UIButton to a method that we’ll call didClickOpenPDF.

Assign Our UIButton To Its Method

The rest of the work will be handled within this “didClickOpenPDF” method in our main ViewController.m.

First, we’ll grab our PDF document from our app bundle.

NSString *file = [[NSBundle mainBundle] pathForResource:@"typo_tips" ofType:@"pdf"];

Next, we’ll create a “ReaderDocument” that our “Reader” will be able to view. Notice that, if our document were password protected, we could set the password as the final parameter.

ReaderDocument *document = [ReaderDocument withDocumentFilePath:file password:nil];

Next, we make sure that our “ReaderDocument” was successfully created, before implementing our “ReaderViewController” which will handle the rest of the PDF operations for us.

if (document != nil)
{
}

And between the braces in the “document” check, we’ll load our “ReaderViewController” object.

if (document != nil)
{
    ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
    readerViewController.delegate = self;
}

In this example, we’ll be presenting our “ReaderViewController” as a modal view, although we could alternatively present it with a UINavigationController if our app were using a UINavigationController. We have various options for the style of presentation and transition that we could use for our ModalViewController, so I’d encourage you to experiment with the styles that work best for your app. In this case, we’ll try to imitate the native Apple PDF style from iBooks.

Add the following lines after “readerViewController.delegate = self;”.

    readerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    readerViewController.modalPresentationStyle = UIModalPresentationFullScreen;

Lastly, we need to actually present our ModalViewController:

[self presentModalViewController:readerViewController animated:YES];

As you can see, once we’ve included our “Reader” library, it’s relatively simple to view and interact with PDFs in our iOS apps. Here’s the entire method that we used:

- (IBAction)didClickOpenPDF:(UIButton *)sender {
NSString *file = [[NSBundle mainBundle] pathForResource:@"typo_tips" ofType:@"pdf"];
ReaderDocument *document = [ReaderDocument withDocumentFilePath:file password:nil];
if (document != nil)
{
    ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
    readerViewController.delegate = self;
    readerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    readerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentModalViewController:readerViewController animated:YES];
}
}

If you run and build our application now, you’ll see the many features already working for your PDF viewer.


Final Product

There’s just one final thing we need to handle: dismissing our PDF Reader ViewController when the user presses the “Done” button.

This is handled with a simple, straightforward method:

- (void)dismissReaderViewController:(ReaderViewController *)viewController {
    [self dismissModalViewControllerAnimated:YES];
}

Step 3: Options

As mentioned earlier, the “Reader” library supports many of these functions beyond just showing PDFs, such as printing, bookmarks, etc. By default, most of these features are enabled. You can, however, choose to set these each as best suits your application by editing the “ReaderConstants.h” file. Each of these features is listed on the “Reader” GitHub page, which I’ll show here:

  • READER_BOOKMARKS – If TRUE, enables page bookmark support.
  • READER_ENABLE_MAIL – If TRUE, an email button is added to the toolbar
    (if the device is properly configured for email support).
  • READER_ENABLE_PRINT – If TRUE, a print button is added to the toolbar
    (if printing is supported and available on the device).
  • READER_ENABLE_THUMBS – If TRUE, a thumbs button is added to the toolbar
    (enabling page thumbnail document navigation).
  • READER_DISABLE_IDLE – If TRUE, the iOS idle timer is disabled while
    viewing a document (beware of battery drain).
  • READER_SHOW_SHADOWS – If TRUE, a shadow is shown around each page
    and the page content is inset by a couple of extra points.
  • READER_STANDALONE – If FALSE, a “Done” button is added to the toolbar
    and the -dismissReaderViewController: delegate method is messaged when
    it is tapped.
  • READER_DISABLE_RETINA – If TRUE, sets the CATiledLayer contentScale
    to 1.0f. This effectively disables retina support and results in
    non-retina device rendering speeds on retina display devices at
    the loss of retina display quality.

Next Time: Writing PDF Documents

Now you’ve seen how easy it can be to view PDFs in iOS. In the next tutorial in this series, we’ll look at some of the ways to create our own PDFs within our Apps.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://sdbwebsolutions.com Serg

    Awesome tutorial!!!

    I’m developing an iphone app for education and this will certainly help me out.

    Can’t wait for the next article:)

  • Martin

    Thanks alot!

  • Rabby ALam

    Is there any way to add search option in this framework ?

    • Paul

      hello! you found a way to add this functionality?

      • ajay

        plz replay here if you have found any thing regarding search option.

    • ajay

      plz replay here if you have found any thing regarding search option

    • ajay

      plz replay here if you have found any thing regarding search option

      • Obaid Shaik

        You can download FastKitPDF reader available on Github to attain that functionality in PDF reader.

        fastpdfkit.com/

  • PACO

    HI, Thanks so much for this great tutorial, it was very helpful and it works awesome. Just one thing, if you change the pdf file for any other that is not the one attached by you, then the Email icon disappears. Also if i rename my pdf with the same name you attached, then the email icon appears but it shows only 9 pages as the original pdf attached by you but my pdf has more pages… i haven’t found the reason or solution, weird isn’t it ? if you ever know the answer please email, as i would love to know what happened there.

    Thanks a lot !

  • Kris

    What would be the best way to load a remote PDF from an NSURL?

  • Shymaa Othman

    Thanks a lot for this great tutorial … Is there a way to edit the library so that pdf scrolls from RIGHT to LEFT ??

  • softs4mobiles

    thanks for this great tutorials i would like to ask how i can read pdf files from url with this projects i used nsurl but it doesn’t work

  • http://twitter.com/Nolan_Ratu Nolan Ratu

    I have added Reader to my project, but the delegate is not working for canceling/send an email not dismissModalView and selecting the done button in the thumbview – xcode 4.5 iOS 6. Thanks

  • Klipnov

    Hi, I’m using this framework to make a Newstand App. Anybody know how to make the viewer show two pdf’s side by side in landscape mode? I’ve seen stackoverflow has quite a lot questions about this but no definite answer.

  • http://twitter.com/Berneau_Berns B&D Crusty Wrecker

    This is SICK! Thanx dude!

  • http://www.facebook.com/ashishkumarpandita Ashish Kumar Pandita

    Great tutortial. Does it have search ?

    • ajay

      please replay here if you have found any thing regarding search option

  • http://www.facebook.com/ammad.aemiee Muhammad Ammad

    Very Useful tutorial can i use this project in my application ? i am developing an OCR and text to speech converter this some part of my project i want your permission ? and also tell me how to access contents of PDF ? for example of page#1 is opened in pdf i want to access all text content of page into a simple textbox is it possible to do this kind of activity ?

  • http://www.facebook.com/profile.php?id=100004079734325 Fatima Khan

    I read your iOS tutorials you got a big collection i am really sure you will help me out actually i need an image cropping tutorial which gets coordinates point in real time from the user and then crop the desired selected area i found this tutorial on a website but i didn’t find source code i contacted them but they didn’t responded to me they approved my comment but they didn’t respond if you could provide me that application same as i found i need that urgently . This is website where i did comment http://crunchmodo.com/image-cropping-application-source-code-for-ios/ and also see some screen shots there this tutorial exactly shows my requirements please help me out i read 3 tutorials from your website and i download source codes and these are really helpful and if you don’t have image Cropping tutorial i suggest you to make it like the one i visited before and i also provided you the URL i am waiting for response please help me out Regards Fatima Khan

  • afghan

    hallo, how can remove Mail button? Thank you.

  • Obaid Shaik

    I developed the application using VFR Reader but not able to figure out how to make it swipe from left to right, for Arabic PDF books. like it should be 5,4,3,2,1 pages currently it is 1,2,3,4,5 arrangement. How can I acheive this anybody can help?

    • saurav sinha

      Hi Obaid,

      Did you get any solution for navigating between pages by swiping from Right to Left to go to the next page?

      If you get any solution then please let me know about it (my mail id: sauravsinha007@gmail.com). I need it urgently.

      Thanks in advance.