I know that it was very unpleasant for me as a novice programmer or even now as an experienced specialist. File I / O through Mail and Safari applications includes very ... interestingly named conventions within the application itself. So let our hands be dirty with the Xcode project for the iPhone. Open Xcode (I will use 4.2 for this tutorial) and select the One View application template (or create an empty project and then add one view using .xib).

In this new application, rename the view controller (and its associated xib) to OfflineReaderViewController , and then we'll move on to the code. (We will touch on each file, but the prefix header and main.m, so keep in mind that you need everything in front of you!)
Enter the AppDelegate header and paste the following code into it:
Then enter the .m delegate file and paste the following code in the transcript:
#import "AppDelegate.h" #import "OfflineReaderViewController.h" @implementation AppDelegate @synthesize window; @synthesize viewController; -(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
- (void)dealloc { [window release]; [viewController release]; [super dealloc]; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
It:
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { if (url != nil && [url isFileURL]) { [self.viewController handleDocumentOpenURL:url]; } return YES; }
It is the single most important part of this lesson. To break it down into appropriate parts: -(BOOL)application:(UIApplication *)application - our -(BOOL)application:(UIApplication *)application application; openURL:(NSURL *)url is the URL that is sent to tell us what to open; sourceApplication:(NSString *)sourceApplication - the application that sent the link; and annotation:(id)annotation is an additional function that we don’t fall into.
Now we have to host our xib. Enter xib (which should have the “OfflineReaderViewController” permission, but that doesn't matter with xib unless we call initWithNibName: (which we won't)) and make it look like the image below:

It’s VERY important that you enter the UIWebView attributes and check “Scales Pages To Fit”, as this allows us to zoom in and out on web pages with tongs. Don't worry about the links until we create them.
Enter the OfflineReaderViewController header and paste the following:
#import <UIKit/UIKit.h> @interface OfflineReaderViewController : UIViewController <UIDocumentInteractionControllerDelegate> { IBOutlet UIWebView *webView; } -(void)openDocumentIn; -(void)handleDocumentOpenURL:(NSURL *)url; -(void)displayAlert:(NSString *) str; -(void)loadFileFromDocumentsFolder:(NSString *) filename; -(void)listFilesFromDocumentsFolder; - (IBAction) btnDisplayFiles; @end
Now .m:
#import "OfflineReaderViewController.h" @implementation OfflineReaderViewController UIDocumentInteractionController *documentController; -(void)openDocumentIn { NSString * filePath = [[NSBundle mainBundle] pathForResource:@"Minore" ofType:@"pdf"]; documentController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]]; documentController.delegate = self; [documentController retain]; documentController.UTI = @"com.adobe.pdf"; [documentController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES]; } -(void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application { } -(void)documentInteractionController:(UIDocumentInteractionController *)controller didEndSendingToApplication:(NSString *)application { } -(void)documentInteractionControllerDidDismissOpenInMenu: (UIDocumentInteractionController *)controller { } -(void) displayAlert:(NSString *) str { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:str delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } - (void)handleDocumentOpenURL:(NSURL *)url { [self displayAlert:[url absoluteString]]; NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; [webView setUserInteractionEnabled:YES]; [webView loadRequest:requestObj]; } -(void)loadFileFromDocumentsFolder:(NSString *) filename {
Those of you who are actively watching and not just copying everything that I tell you (just joking) will know that this line: [[NSBundle mainBundle] pathForResource:@"Minore" ofType:@"pdf"]; will give us SIGABRT because, well, the file does not exist! So, drag it into any shared PDF file that you pulled from anywhere (I recommend here because who does not spend their free time reading huge volumes of documentation?), Then copy its name and paste it with the removed suffix (.pdf) ; part ofType:@"pdf" will take care of this for us. The line should look like as soon as you finish: [[NSBundle mainBundle] pathForResource:@"//file name//" ofType:@"pdf"];
Now go back to xib and plug in those IBOutlets ! That's it, this is what your Owner File tab should look like:

It seems we are done ... but wait! We did nothing to open the "Open in ..." menu! Well, it turns out that there is some kind of error in the .plist file. Open the .plist application (quick right-click, then select "Open As> Source Code") and paste the following:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleDisplayName</key> <string>${PRODUCT_NAME}</string> <key>CFBundleExecutable</key> <string>${EXECUTABLE_NAME}</string> <key>CFBundleIconFiles</key> <array/> <key>CFBundleIdentifier</key> <string>CodaFi.${PRODUCT_NAME:rfc1034identifier}</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>${PRODUCT_NAME}</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>1.0</string> <key>LSRequiresIPhoneOS</key> <true/> <key>UIRequiredDeviceCapabilities</key> <array> <string>armv7</string> </array> <key>UISupportedInterfaceOrientations</key> <array> <string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array> <key>UIFileSharingEnabled</key> <true/> <key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeName</key> <string>PDF Document</string> <key>LSHandlerRank</key> <string>Alternate</string> <key>CFBundleTypeRole</key> <string>Viewer</string> <key>LSItemContentTypes</key> <array> <string>com.adobe.pdf</string> </array> </dict> </array> </dict> </plist>
[Lateral note: be careful when cheating the source code of any plist, if you don’t know what you are doing, you may get the terrible "This file was damaged" error from Xcode]
If you need to right-click and select Open As> Property List, it will look like this:

There's still a VERY important field in the title "Application supports iTunes file sharing." This must be set to "YES" or your application will not be displayed in iTunes as support for file sharing.
The "Document types" field indicates the types of documents that our example can open. Expand the arrow to find its role and UTI. These are unique identifiers (unique type identifiers, it seems obvious what this abbreviation means, right?), What each kind of file has. UTI is what allows finder to replace the overall document image with this beautiful localized file type image (don’t believe me, rename the non-essential file extension to .ouhbasdvluhb and try to get a beautiful image!) If I wanted to open (say, a .code file) then I would put something like com.CodaFi.code (reverse DNS record for those who don’t have a hint) in the UTI field and the Document Type Name would be “Document CodaFi”. The rank and role of the handler should be understood, because our handler rank is alternative (because we don’t have a file), and our role is the viewer (because we don’t need anything more important. Our example is just a viewer, not an editor, therefore we will leave it as such.
For future use, UTI has official system-declared naming schemes when they come from reputable sources (Oracle, Microsoft, even Apple itself), which can be found in the Unified Name Type Reference Guide , but are listed here for the radiant.
Now, let run 'er! The code should be built without errors, assuming that you copied the shorthand and received these damned xib connections. Now, when you first start the application, you should be given the opportunity to open the document in iBooks. Deselect the real meat code opens other documents! Launch Safari and find any PDF file that Safari can open QuickLook or open. Then in the menu "Open in ..." our application will appear! Click on it. You will get a small switcheroo animation and a file location warning will appear. When you reject it, UIWebView download the PDF file. The Mail application has similar functionality with attachments. You can also call these PDF files for your application.
What is it all done. Enjoy and happy coding!