How to Open and View PDF Files in iOS

Updated on February 7, 2018
klanguedoc profile image

Kevin is Software Developer with 20 years experience designing and building business intelligence and system integration solutions.

Source

There are different ways to open and view a PDF file in an iOS application. First, you use the UIWebView, which I will demonstrate in this tutorial, you can also use the UIDocumentInteractionController class to open and view PDF files using the presentPreviewAnimated and dismissPreviewAnimated methods or the CGPDFDocumentRefclass in the Core Foundation framework. Each offers an easy way to open and view PDF documents

As previously cited, I will use the UIWebView to load a PDF document that is located in the Documents directory. This tutorial is an extension of a previous tutorial that demonstrated how to create PDF using the UIKit: iOS Create PDF using UIKit. In this tutorial, I will add a View Controller and an UIPickerView to load PDFs files in the Documents and display the PDF in another View Controller.

Application Tutorial Steps

You can either use the source code from the previous tutorial that you can download, or build an application from scratch, either way, you will start with a blank UIViewController.

  1. Add a UIViewController to the existing project or create a Single View Controller application.
  2. Add an UIPickerView to the UIViewController.
  3. Add an UIButton to the UIViewController beneath the UIPickerView.
  4. Change the button’s label to the following by clicking on it: “Load PDF”.
  5. If this a new UIViewController in an existing project, add a new file as a subclass of the UIViewController, taking care to not create a xib file. Name it listPDFVC.
  6. Again if this is a new UIViewController, add the newly created UIViewController subclass to the custom class field in the Identity inspector. Otherwise, you can skip this step.
  7. Drag a connection from the UIPickerView to the UIViewController proxy and select the delegate from the outlets. Repeat the same process and select the data source. This will bind the delegate and data source protocols that we will define in the header file next.
  8. Open the header file and drag a connection from the UIPickerView to the header file between the @interface and @end directives. Releasing the mouse a popover will appear allowing you to name the IBOutlet: listPDF.
  9. Before getting to the header and implementation files, add another UIViewController to the Storyboard.
  10. Next, add a UIWebView to this new UIViewController.
  11. Now drag a connection from the UIButton in the first UIViewController to the new UIViewController making sure not to release the connection string on the UIWebView. Rather release it near the top of the UIViewController. This will be the segue.
  12. With the segue selected, switch to the attributes inspector and give the segue an identifier (name) like pdfSegue.
  13. Next, create a new custom class as a subclass of the UIViewController. Name it displayPDFVC.
  14. Add this new UIViewController subclass to the UIViewController through the custom class field in the Identity inspector.
  15. Now open the header file by selecting the Editor assistant as before and drag a connection from the UIWebView to the header file. Name this IBOutlet: displayPDF.


With the Storyboard complete, we can add the logic to make it all work.

ListPDFVC Logic

  • Open the ListPDFVC header and add an import statement for the ViewPDFVC.h class.
  • Next add the UIPickerViewDataSource and UIPickerViewDelegate protocols as in the source code below.
  • Add a NSMutableArray property. Call it: pdfList.
  • Then add a NSString property for the selected file name in the UIPickerView. Name it: pickerSelectedFile.
  • Finally add a method to populate the pdfList property. Name this method loadPDFList as in the source code.

ListPDFVC.h

//
//  ListPDFVC.h
//  PDF Creator
//
//  Created by Kevin Languedoc on 11/23/12.
//  Copyright (c) 2012 Kevin Languedoc. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "ViewPDFVC.h"

@interface ListPDFVC : UIViewController<UIPickerViewDataSource,UIPickerViewDelegate>
@property (strong, nonatomic) IBOutlet UIPickerView *listPDF;

@property(strong,nonatomic) NSMutableArray * pdfList;
@property(strong,nonatomic) NSString *pickerSelectedFile;

-(void)loadPDFList;
@end
  • Finally open the implementation file and synthesize the properties using the @synthesize directive.
  • Add the loadPDFList method as in the source code.
  • Add a NSFileManager variable and set it the defaultManager which is the root directory.
  • Add a variable for the the path of the Documents directory using the NSSearchPathForDirectoriesInDomains and NSDocumentsDirectory which will add one element to the docDirArr NSArray
  • Assign the path of the Documents directory to the docDir NSString which will used to get the contents of the directory as a NSArray and assign the values to the dirContents NSArray.
  • Although not necessary since the documents directory only contains pdf file, I add a filter using the NSPredicate class to filter on pdf files only
  • Finally add the filtered array to the __pdfList NSMutableArray which will serve as the data source for the UIPickerView to complete the loadPDFList method.
  • Add the viewDidAppear of the UIViewController. In it call the loadPDFList as in the source code. This method is called every time after the first time.
  • Also add the listPDF reloadAllComponents method to refresh the UIPickerView when new files are added to the NSMutableArray.
  • In the ViewDidLoad method call the loadPDFList method as previously cited.
  • Add the required pickerView:numberOfRowsInComponent method returning the listPdf count to define the number of rows that the UIPickerView will contain.
  • The required numberOfComponentsInPickerView method defines the number of columns to display. In this example I set the return value to 1.
  • The required pickerView:titleForRow:forComponent method defines the value to display in the UIPickerView. Fro this I set the filenames as the value to display.
  • The pickerView:didSelectRow method assigns the selected value in the UIPickerView to the selectedPDFFile variable which we will pass tot he next UIViewController.
  • The final method to implement is the prepareForSegue method that works in conjunction with the segue. Since I only have one segue I don't check to see which segue is called but for multiple segues this is important.
  • Create a instance of the viewPDFVC class and assign it to the destinationViewController to set the target ViewController.
  • Finally assign the value of the selectedPDFFile variable to the selectedFile variable of the viewPDFVC. This will trigger the viewPDFVC to be pushed onto the stack.

ListPDFVC.m

//
//  ListPDFVC.m
//  PDF Creator
//
//  Created by Kevin Languedoc on 11/23/12.
//  Copyright (c) 2012 Kevin Languedoc. All rights reserved.
//

#import "ListPDFVC.h"

@interface ListPDFVC ()

@end

@implementation ListPDFVC
@synthesize listPDF;
@synthesize pickerSelectedFile;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view.
    [self loadPDFList];
}
-(void)viewDidAppear:(BOOL)animated{
     [self loadPDFList];
    [listPDF reloadAllComponents];
}

- (void)viewDidUnload
{
  
    [self loadPDFList];
    [self setListPDF:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    ViewPDFVC * viewPDF = [segue destinationViewController];
    viewPDF.selectedFile = pickerSelectedFile;
}

-(void)loadPDFList{
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    NSArray *docDirArr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [docDirArr objectAtIndex:0];
    NSArray *dirContents = [fileMgr contentsOfDirectoryAtPath:docDir error:nil];
    NSPredicate *extFilter = [NSPredicate predicateWithFormat:@"self ENDSWITH '.pdf'"];
    _pdfList = [[NSMutableArray alloc] initWithArray:[dirContents filteredArrayUsingPredicate:extFilter]];
    
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    
    return [_pdfList count];
}

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 1;
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row
            forComponent:(NSInteger)component
{
    
    
    return [_pdfList objectAtIndex:row];
    
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    
    
    
    pickerSelectedFile = [_pdfList objectAtIndex:row];
    
    
    
}


@end

ViewPDFVC

  • In the header add a class directory to the current class as @class ViewPDFVC
  • Also add a NSString variable called, selectedFile which will contain the file whose contents will be displayed in the UIWebView.
  • In the implementation, synthesize the selectedFile variable
  • Also in the implementation file, the main method that will display the PDF contents will be the viewDidAppear which will be called when the view controller is loaded.
  • In this method, we get a handle on the Documents directory as before
  • Then assign the path of the PDF file to the pdfPath NSString variable and then passing this value to the NSURL variable pdfURL which will be used to load the file and its contents.
  • Next create a NSUrlRequest variable called pdfReq and initialize the variable using theinitWithURL method with the pdfUrl value.
  • Finally call the pdfViewer UIWebView and call the loadRequest method and passing thepdfReq variable's value to be displayed in the UIWebView

ViewPDFVC.h

//
//  ViewPDFVC.h
//  PDF Creator
//
//  Created by Kevin Languedoc on 11/25/12.
//  Copyright (c) 2012 Kevin Languedoc. All rights reserved.
//

#import <UIKit/UIKit.h>

@class ViewPDFVC;
@interface ViewPDFVC : UIViewController
@property (strong, nonatomic) IBOutlet UIWebView *pdfViewer;

@property (strong, nonatomic) NSString *selectedFile;
@end

ViewPDFVC.m

//
//  ViewPDFVC.m
//  PDF Creator
//
//  Created by Kevin Languedoc on 11/25/12.
//  Copyright (c) 2012 Kevin Languedoc. All rights reserved.
//

#import "ViewPDFVC.h"

@interface ViewPDFVC ()

@end

@implementation ViewPDFVC

@synthesize pdfViewer, selectedFile;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view.
}

-(void)viewDidAppear:(BOOL)animated{
    NSArray * docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    
    //Define new path for database in the documents directory because data cannot be written in the resource folder.
    NSString * pdfPath = [[docPath objectAtIndex:0] stringByAppendingPathComponent:selectedFile];
    NSURL *pdfURL = [[NSURL alloc]initFileURLWithPath:pdfPath];
    NSURLRequest *pdfReq = [[NSURLRequest alloc] initWithURL:pdfURL];
    [pdfViewer loadRequest:pdfReq];
}

- (void)viewDidUnload
{
    [self setPdfViewer:nil];
  
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

© 2012 Kevin Languedoc

Comments

    0 of 8192 characters used
    Post Comment

    • klanguedoc profile imageAUTHOR

      Kevin Languedoc 

      5 years ago from Canada

      Hey thanks tillsontitan LOL. It does start to make sense the more you learn and use it.

    • tillsontitan profile image

      Mary Craig 

      5 years ago from New York

      I'm afraid this is out of my league Klanguedoc...I use Adobe Reader and skip all the technical stuff. I voted this up because it is amazing!

    working

    This website uses cookies

    As a user in the EEA, your approval is needed on a few things. To provide a better website experience, turbofuture.com uses cookies (and other similar technologies) and may collect, process, and share personal data. Please choose which areas of our service you consent to our doing so.

    For more information on managing or withdrawing consents and how we handle data, visit our Privacy Policy at: https://turbofuture.com/privacy-policy#gdpr

    Show Details
    Necessary
    HubPages Device IDThis is used to identify particular browsers or devices when the access the service, and is used for security reasons.
    LoginThis is necessary to sign in to the HubPages Service.
    Google RecaptchaThis is used to prevent bots and spam. (Privacy Policy)
    AkismetThis is used to detect comment spam. (Privacy Policy)
    HubPages Google AnalyticsThis is used to provide data on traffic to our website, all personally identifyable data is anonymized. (Privacy Policy)
    HubPages Traffic PixelThis is used to collect data on traffic to articles and other pages on our site. Unless you are signed in to a HubPages account, all personally identifiable information is anonymized.
    Amazon Web ServicesThis is a cloud services platform that we used to host our service. (Privacy Policy)
    CloudflareThis is a cloud CDN service that we use to efficiently deliver files required for our service to operate such as javascript, cascading style sheets, images, and videos. (Privacy Policy)
    Google Hosted LibrariesJavascript software libraries such as jQuery are loaded at endpoints on the googleapis.com or gstatic.com domains, for performance and efficiency reasons. (Privacy Policy)
    Features
    Google Custom SearchThis is feature allows you to search the site. (Privacy Policy)
    Google MapsSome articles have Google Maps embedded in them. (Privacy Policy)
    Google ChartsThis is used to display charts and graphs on articles and the author center. (Privacy Policy)
    Google AdSense Host APIThis service allows you to sign up for or associate a Google AdSense account with HubPages, so that you can earn money from ads on your articles. No data is shared unless you engage with this feature. (Privacy Policy)
    Google YouTubeSome articles have YouTube videos embedded in them. (Privacy Policy)
    VimeoSome articles have Vimeo videos embedded in them. (Privacy Policy)
    PaypalThis is used for a registered author who enrolls in the HubPages Earnings program and requests to be paid via PayPal. No data is shared with Paypal unless you engage with this feature. (Privacy Policy)
    Facebook LoginYou can use this to streamline signing up for, or signing in to your Hubpages account. No data is shared with Facebook unless you engage with this feature. (Privacy Policy)
    MavenThis supports the Maven widget and search functionality. (Privacy Policy)
    Marketing
    Google AdSenseThis is an ad network. (Privacy Policy)
    Google DoubleClickGoogle provides ad serving technology and runs an ad network. (Privacy Policy)
    Index ExchangeThis is an ad network. (Privacy Policy)
    SovrnThis is an ad network. (Privacy Policy)
    Facebook AdsThis is an ad network. (Privacy Policy)
    Amazon Unified Ad MarketplaceThis is an ad network. (Privacy Policy)
    AppNexusThis is an ad network. (Privacy Policy)
    OpenxThis is an ad network. (Privacy Policy)
    Rubicon ProjectThis is an ad network. (Privacy Policy)
    TripleLiftThis is an ad network. (Privacy Policy)
    Say MediaWe partner with Say Media to deliver ad campaigns on our sites. (Privacy Policy)
    Remarketing PixelsWe may use remarketing pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to advertise the HubPages Service to people that have visited our sites.
    Conversion Tracking PixelsWe may use conversion tracking pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to identify when an advertisement has successfully resulted in the desired action, such as signing up for the HubPages Service or publishing an article on the HubPages Service.
    Statistics
    Author Google AnalyticsThis is used to provide traffic data and reports to the authors of articles on the HubPages Service. (Privacy Policy)
    ComscoreComScore is a media measurement and analytics company providing marketing data and analytics to enterprises, media and advertising agencies, and publishers. Non-consent will result in ComScore only processing obfuscated personal data. (Privacy Policy)
    Amazon Tracking PixelSome articles display amazon products as part of the Amazon Affiliate program, this pixel provides traffic statistics for those products (Privacy Policy)