Preview Documents Tutorial with QLPreviewController

Mon, May 9

For the past few months I’ve been meaning to spend some time to check out the quick look document previewer on iOS – what follows is a short app that I wrote to get familiar with the QLPreviewController API.

For those unfamiliar with the quick look previewer, it is a framework that provides quick previewing of a range of document types – supported documents include iWork documents, Microsoft Office, Rich Text Format, PDF, images, text files and comma-separated (csv) files.

Document Previewer Demo App

What follows are a few screenshots of the previewer application covered in this post. I’ve added three different file types in the application, an image, a pdf and an MS Office document. The screenshot in the upper left is the list of available files to preview. In the lower left is Remodel.xls, an Excel document. The upper right screenshot is the iOSDevTips.png image. Notice in this same image in the upper right corner is a directional arrow (outlined with the red box), this leads you to one nice addition you get for free with preview, support for printing (assuming you have a wireless printer in the vicinity).

Document Previewer Interface

The interface file for the application is shown below, notice the reference to the QL Data Source, when using the QLPreviewController you must adopt this protocol. The only instance variable is an array that will hold strings value representing the title of each document available for previewing. The UITableViewController class will be used to display the list of documents to preview.

#import <QuickLook/QuickLook.h>
 
@interface TestViewController : UITableViewController <QLPreviewControllerDataSource>
{
  NSArray *arrayOfDocuments;
}
 
@end
Document Previewer Implementation

In this section I’ll show a selection of code applicable to setting up the previewer. The code for creating the table view and populating the same can be viewed in the Xcode project which you can download from the link below.

The initialization code populates the array of document names:

-(id)init
{
  if (self = [super init])
  {
    arrayOfDocuments = [[NSArray alloc] initWithObjects: 
        @"iOSDevTips.png", @"Remodel.xls", @"Core J2ME Technology.pdf", nil];
  }
  return self;
}

The method below is one of the two required when adopting the QLPreviewControllerDataSource protocol, this method informs the preview controller how many items are in the preview navigation list:

- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller 
{
  return [arrayOfDocuments count];
}

The method that does all the work (other than the previewer itself of course) is shown below – this method returns a NSURL object of the item to display. Given the objects to display are packaged within the application, I create a path to the relevant file in the application bundle and return a URL using that same path.:

- (id <QLPreviewItem>)previewController: (QLPreviewController *)controller previewItemAtIndex:(NSInteger)index 
{
  // Break the path into its components (filename and extension)
  NSArray *fileComponents = [[arrayOfDocuments objectAtIndex: index] componentsSeparatedByString:@"."];
 
  // Use the filename (index 0) and the extension (index 1) to get path
  NSString *path = [[NSBundle mainBundle] pathForResource:[fileComponents objectAtIndex:0] ofType:[fileComponents objectAtIndex:1]];
 
  return [NSURL fileURLWithPath:path];
}

The remaining code in the project is typical iPhone/iOS stuff, creating the app delegate, adding a subview (a navigation controller) to the delegate’s UIWindow and making the window visible. I’ve included code from the delegate below, here you can get the bigger picture view of how I setup the view controller for this application.

- (void)applicationDidFinishLaunching:(UIApplication *)application 
{   
  // Create and initialize the window
  window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
 
  // Create test view controller
  vc = [[TestViewController alloc] init];
 
  // Create navigation controller 
  nav = [[UINavigationController alloc] initWithRootViewController:vc];
 
  [window addSubview:[nav view]];  
  [window makeKeyAndVisible];
}

One point worth mentioning is that you have two different options when working with a preview controller. First, you can push the object with the preview controller onto a view using a UINavigationController object, which you can see is what I’ve done here. The preview controller for my app lives in TestViewController and this object is set as the root view controller for a navigation controller.

The second approach to display the preview controller is modally, using the method presentModalViewController.

Document Previewer Source Code

Xcode project for iPhone Document Previewer

9 comments

Is there a way to disable the printer action button?

When the files reside locally, the printer button works fine.

So if your files are local, you can build the url with NSURL fileURLWithPath:

However, if the files reside on a server, you build the url with NSURL URLWithString:

An app will crash if you try printing when previewing items with URLWithString.

by jb on Jun 10, 2011. #

Is there a way to suppress the share button completely (disable both the share to iBooks and print)?

by dk on Aug 24, 2011. #

10x for the great example!

i was wondering if it is possible to turn the black background of the image preview to white.
anyone?

by art on Sep 18, 2011. #

what does 10x mean ?

by arf on Sep 28, 2011. #

Nice example!

I see the previewItemAtIndex requires a url.
My data is in a base64encoded string, what should be the approch to achive this.
Should i save my file first to disk and delete it later again?

by Gertjan on Mar 14, 2012. #

Nice example !!!

But is there any way to edit the documents like Excel, Word using the same class ?Since I didn;t find any way of doing this using same class.

Other than this, if any other way of doing this .

by Ajay Sharma on Jul 9, 2012. #

Unfortunately there is no API to edit

by John Muchow on Jul 9, 2012. #

How about setting the TITLE of the document instead of the filename which shows by default ?

by Craig on Sep 10, 2012. #

Hi,

I have a little problem. Everything works fine if the path is like :

https://developer.apple.com/library/ios/DOCUMENTATION/NetworkingInternet/Reference/QLPreviewController_Class/QLPreviewController_Class.pdf

but if my path is a mysql query only the text file are right view, don’t work for pdf, word, excel, ….

http://myweb.com/ios/download.php?upl_P=698“.

Maybe I must decode the file ?

Thanks

by Ferran on Oct 8, 2012. #