原文

System-Declared Uniform Type Identifiers

One of the common tasks that an iOS developer has to do is to import or export documents from his iOS application. For example, suppose you are developing a document reader and you want to allow the user to import documents into your application so that it can be read offline. Also, your reader might also support the exporting of documents so that other applications can make use of the document.

In this article, I will walk you through the different techniques you can employ to allow documents to be imported or exported from your iOS application.

Creating the Project

As usual, I will be using an example to illustrate the various techniques discussed in this article. Using Xcode, create a new View-based Application (iPhone) project and name it OfflineReader.

Double-click on the OfflineReaderViewController.xib to open it in Interface Builder and populate it with the following views (see Figure 1):

    • WebView
    • Round Rect Button


      Figure 1. Populating the View window

      In the Attributes Inspector window for the WebView, ensure that you check the “Scales Page to Fit” item.

      In the OfflineReaderViewController.xib file, add in the following statements in bold:

      #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

      Back in Interface Builder, connect the outlet and action to the WebView and Button views. Right-clicking on the File’s Owner in the OfflineReaderViewController.xib window should now reveal the connections as shown in Figure 2.


      Figure 2. Confirmation the connections of the action and outlet

      Drag and drop two files into the Resources folder of the project (see Figure 3). In this example, I have a PDF file named “Courses for Q2 2011.pdf” and an image file named icon.jpg.


      Figure 3. Adding two files to the Resources folder of the project

      In the OfflineReader-Info.plist file, set the “Icon file” key to “icon.jpg”.

      So now you have an iPhone application with the icon set. It also has a PDF document in the Resources folder.

      Exporting Documents

      The first thing you will learn is how to export a document from your application. For example, in the Mail application on your iPhone, when you received a PDF file, you can either tap on the icon (see Figure 4) to view the document within the Mail application, or tap and hold onto the icon.


      Figure 4. A PDF document in Mail

      If you do the latter, an action sheet would be displayed (see Figure 5). You can tap on the “Open in...” button to see a list of applications that your document can be exported to.


      Figure 5. Viewing your application in an external application

      In my case, it will display the list as shown in Figure 6.


      Figure 6. A list of applications able to handle your document

      So let’s now modify our application so that we can export the PDF document in the Resources project to an external application.

      First, declare a variable of type UIDocumentInteractionController in the OfflineReaderViewController.m file:

      #import "OfflineReaderViewController.h"
       
      @implementation OfflineReaderViewController
       
      UIDocumentInteractionController *documentController;

      The UIDocumentInteractionController class provides in-app support for providing user interaction with files in your application. In this example, you will use it to export a document to an external application.

      Next, define the following methods:

      -(void)openDocumentIn {
      NSString * filePath =
      [[NSBundle mainBundle]
      pathForResource:@"Courses for Q2 2011" 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 {
       
      }

      The openDocumentIn method basically creates the path to point to the PDF document (that you want to export) and then uses it to feed into the documentController object. You need to set the UTI (Uniform Type Identifiers) for the documentController object so that it can help the system find the appropriate application to open your document. In this case, it is set to “com.adobe.pdf”, which represents a PDF document. Other common UTIs are "com.apple.quicktime-movie" (QuickTime movies), "public.html" (HTML documents), and "public.jpeg" (JPEG files).

      The other three methods are the methods defined in the UIDocumentInteractionControllerDelegate protocol. They are fired when the documentController object is being invoked. For this example, you don’t really need to code anything within these methods.

      Finally, in the viewDidLoad method, add the following statement:

      - (void)viewDidLoad {
      [super viewDidLoad];
      [self openDocumentIn];
      }

      Press Command-R to test the application on a real device (the Simulator won't work in this case). When the View window is loaded, you will see an action sheet displaying the list of applications that you can export your document to (see Figure 7).


      Figure 7. Exporting our PDF document to an external application

      If you select iBooks, the PDF document will appear in iBooks (see Figure 8).


      Figure 8. iBooks showing our PDF document

      File Sharing

      The previous section showed how you can export a document to an external application. What about the other way round – importing a document into your application? In iOS, there are two ways to get files into your application:

      • File Sharing through iTunes
      • Through exchanges between applications (like the one you just saw in the previous section)

      Let’s discuss the first method first. The first method presents a very easy and direct way for users to transfer large number of files into or out of an application. In the OfflineReader-Info.plist file, add a new key named UIFileSharingEnabled and check it (see Figure 9).


      Figure 9. Adding a new key to enable file sharing for your application

      Press Command-R to redeploy the application onto the real device again. Launch iTunes and select the device name, followed by the Apps tab. Figure 10 shows that the OfflineReader application now appears under the File Sharing section.


      Figure 10. The application is now listed under the File Sharing section of iTunes

      To copy a file into the application, simply drag and drop it into the rectangle labeled OfflineReader Documents. Figure 11 shows that I have copied a PDF document into the application. All documents copied will reside in the Documents folder of your application.


      Figure 11. Copying a document into the application

      If you want to extract the files from the application and save it locally onto your computer, select the file(s) and click the Save to… button.

      Now, to prove that the files are really copied into the Documents folder of your application, add the following code to the OfflineReaderViewController.m file:

      -(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 {
      NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
      [webView setUserInteractionEnabled:YES];
      [webView loadRequest:requestObj];
      }
       
      -(void)loadFileFromDocumentsFolder:(NSString *) filename {
      //---get the path of the Documents folder---
      NSArray *paths = NSSearchPathForDirectoriesInDomains(
      NSDocumentDirectory, NSUserDomainMask, YES);
      NSString *documentsDirectory = [paths objectAtIndex:0];
      NSString *filePath = [documentsDirectory
      stringByAppendingPathComponent:filename];
      NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
      [self handleDocumentOpenURL:fileUrl];
      }
       
      -(void)listFilesFromDocumentsFolder {
      //---get the path of the Documents folder---
      NSArray *paths = NSSearchPathForDirectoriesInDomains(
      NSDocumentDirectory, NSUserDomainMask, YES);
      NSString *documentsDirectory = [paths objectAtIndex:0];
       
      NSFileManager *manager = [NSFileManager defaultManager];
      NSArray *fileList =
      [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];
      NSMutableString *filesStr =
      [NSMutableString stringWithString:@"Files in Documents folder \n"];
      for (NSString *s in fileList){
      [filesStr appendFormat:@"%@ \n", s];
      }
      [self displayAlert:filesStr];
      [self loadFileFromDocumentsFolder:@"0470918020.pdf"];
      }
       
      - (IBAction) btnDisplayFiles {
      [self listFilesFromDocumentsFolder];
      }

      Here, the displayAlert: method is simply a helper method to display an Alert View on the screen. The handleDocumentOpenURL: method takes in a NSURL object and loads the WebView with its content. The loadFileFromDocumentsFolder: method takes in a filename and converts its path into a NSURL object. The listFilesFromDocumentsFolder method displays all the files and folders contained within the Documents folder of the application. Here, I have hardcoded it to display the PDF document named “0470918020.pdf” (which is what I have copied earlier).

      Press Command-R to deploy the application on the device again. Tapping the Display files in Documents button will display the filename and at the same time load the PDF document in the WebView (see Figure 12), proving that the file was transferred into the application successfully.


      Figure 12. Displaying the files in the Documents folder and loading the PDF document

      Importing Documents

      The second method to transfer documents into an application is through another application (as seen in the first section of this article). In the beginning of this article, you saw how a PDF document in your application can be transferred to the iBooks application for viewing. This time round, you will learn how a document can be transferred into your own application.

      For a start, you shall modify the application to accept PDF documents. What you need to do is to get your application to register with the iOS that it is able to accept PDF document. To do this, you need to modify the OfflineReader-Info.plist file.

      Add the new CFBundleDocumentTypes key as shown in Figure 13.


      Figure 13. Add a new key to support PDF documents

      Note the following:

      • The CFBundleDocumentTypes key is of type Array. It contains an array of dictionaries describing the types of documents supported by your application.
      • Item 0 is of type Dictionary.
      • The CFBundleTypeName key specifies the abstract name for the specified document type.
      • The LSHandlerRank key specifies whether the application is the owner (creator of this file type), Alternate (secondary viewer of this file type), None, or Default.
      • The CFBundleTypeRole key specifies the application’s role with respect to the type - Editor, Viewer, Shell, or None.
      • The LSItemContentTypes key is of type Array. It contains an array of UTIs specifying the file type.

      The above entry in the OfflineReader-Info.plist file will register with iOS that the application is capable of handling PDF documents.

      When a PDF document is passed into the application, the application will fire a particular method – application:openURL:sourceApplication:annotation:. This method must be implemented in the application delegate.

      Hence, add the following in the OfflineReaderAppDelegate.m file:

      #import "OfflineReaderAppDelegate.h"
      #import "OfflineReaderViewController.h"
       
      @implementation OfflineReaderAppDelegate
       
      @synthesize window;
      @synthesize viewController;
       
      -(BOOL)application:(UIApplication *)application
      openURL:(NSURL *)url
      sourceApplication:(NSString *)sourceApplication
      annotation:(id)annotation {
      if (url != nil && [url isFileURL]) {
      [self.viewController handleDocumentOpenURL:url];
      }
      return YES;
      }

      When a document is passed into your application, it will be copied into a folder called Inbox, located within the Documents folder. The url argument contains the path to the document in the Inbox folder. In the above, once the document is passed in, you will call the handleDocumentOpenURL: method defined in the OfflineReaderViewController class to load the document in the WebView.

      To see the URL of an imported document, add the following statement to the handleDocumentOpenURL: method:

      - (void)handleDocumentOpenURL:(NSURL *)url {
      [self displayAlert:[url absoluteString]];
      NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
      [webView setUserInteractionEnabled:YES];
      [webView loadRequest:requestObj];
      }

      Press Command-R to deploy the application onto the real device again. This time, if you go back to the same email containing the PDF document and tap and hold on to it, you will find that you have the option to open the document in the OfflineReader application (see Figure 14).


      Figure 14. Your application is capable of handling PDF document

      When the document is opened in OfflineReader, you will see the path of the document as shown in Figure 15.


      Figure 15. Confirming the path of the document in the Documents/Inbox folder

      Importing Self-Defined Documents

      The previous section showed how to import well-known document types, such as PDF. What happens if you want to import your own self-defined document types? For example, you are writing a Sudoku game and wanted to implement your own file format for saving the state of a Sudoku game. In this case, your file might have the .sdk extension, which is only used by your application.

      To ensure that your application can handle files with the .sdk extension, you will add the keys as shown in Figure 16 to the OfflineReader-Info.plist file.


      Figure 16. Adding new keys to support self-defined document types

      Note that you added another key to the CFBundleDocumentTypes array. You set the LSItemContentTypes to a unique value, using the reverse domain name of your company and the type you are defining. Since this is a self-defined content type, you have to define it using the UTExportedTypeDeclarations key.

      Note: For more information on UTI, refer to Apple’s documentations – “Introduction to Uniform Type Identifiers Overview”.

      Press Command-R to test the application on a real device again. This time round, if your email contains a document of extension .sdk, you will see the icon of your application displayed next to the document name (see Figure 17). When you tap on the document name, you will see a list of options to open your documents with.


      Figure 17. Opening a file of type .sdk

      Summary

      In this article, you have seen the different techniques for handling documents in your application. With this knowledge, you will be able to write cool iOS applications that allows them to interact with the outside world!

转:IOS程序之间的文件共享的更多相关文章

  1. ios 应用程序之间的跳转(内置程序的实现)

    ios 应用程序之间的跳转(内置程序的实现) 一个程序若要跳到另一个程序.需要在目标程序的plist文件里面修改: 打开info.plist,添加一项URL types 展开URLtypes,再展开I ...

  2. iOS开发系列-应用程序之间跳转

    概述 常见的涉及到应用程序之间的跳转场景,比如社交分享.支付宝.微信支付.链接跳转到应用. 在iOS中应用跳转的本质:打开一个应用只需要拿到对应应用的URL即可. 统一资源定位符 URL(统一资源定位 ...

  3. iOS程序开发引用的第三方库之间出现duplicate symbol时的处理方法

    iOS程序集成的第三方库过多时,很容易出现某几个库同时用到了一样的函数库,也就是在你的程序link时会提示duplicate symbol,而重复的符号又不是由你自己程序的代码造成的,也就说没法通过直 ...

  4. iOS开发系列--IOS程序开发概览

    概览 终于到了真正接触IOS应用程序的时刻了,之前我们花了很多时间去讨论C语言.ObjC等知识,对于很多朋友而言开发IOS第一天就想直接看到成果,看到可以运行的IOS程序.但是这里我想强调一下,前面的 ...

  5. iOS程序-UIScrollView的基本使用

    iOS程序-UIScrollView的基本使用 scrollView的几个属性contentSize contentOffset contentInset 1.不能向上滑动很可能是因为contentS ...

  6. 从此走上一条iOS程序猿不归路。。。

    新的城市,新的生活!前不久刚刚结束了苦逼的面试找工作之旅,期间也小有收货,如今正处年底工作闲暇之余,将前一阵子陆陆续续的总结整理了一下,本人菜鸟程序猿一只,水平有限,本文总结的知识不算深入,比较浅显, ...

  7. iOS程序员对算法的要求

    算法和数据结构(鉴于二者的关联,以下统称算法),对于程序员的重要性一直是个具有争议性的话题.有一些程序员内心对算法有着天然的排斥,面试当中一旦考察算法知识,会被不少程序员吐槽,但有部分公司又一直在坚持 ...

  8. iOS基础 - iOS程序启动原理

    一.UIApplicationMain 在main.m的main函数中执行了UIApplicationMain这个方法,这是ios程序的入口点 int UIApplicationMain(int ar ...

  9. 如何在RHEL7上搭建Samba服务实现Windows与Linux之间的文件共享

    如何在RHEL7上搭建Samba服务实现Windows与Linux之间的文件共享 实现环境:VMware workstations.RHEL7.0 第一步:配置网卡IP及yum软件仓库 命令:vim ...

随机推荐

  1. python爬虫知识点总结(三)urllib库详解

    一.什么是Urllib? 官方学习文档:https://docs.python.org/3/library/urllib.html 廖雪峰的网站:https://www.liaoxuefeng.com ...

  2. jdk安装图解--windows系统(第一次安装和第二次安装区别)

    第一次安装可参考 https://jingyan.baidu.com/article/22fe7cedc9b93e3003617f64.html 第二次安装,如已经配置好环境变量,cmd下执行java ...

  3. IOS深入学习

    iOS超全开源框架.项目和学习资料汇总(1)UI篇 iOS超全开源框架.项目和学习资料汇总(2)动画篇 iOS超全开源框架.项目和学习资料汇总(3)网络和Model篇 数据库 FMDB – sqlit ...

  4. [poj3140]Contestants Division树形dp

    题意:切掉树上的某条边,使分开的两棵树上各点的权值和差值最小. 与hdu2196不同的是,此题是点权,其他无太大差别,注意数据范围. 先求出每个节点的子树权值和,然后自底向上dp即可.取$\min ( ...

  5. installshield 6109错误解决方案

    电脑重装了一下过后,运行打包程序就一直报6109错误,网上也没有查找出相关答案,真是急死了,后来无意发现输出项目的发布路径和当前自己setup的路径不一致,由于移动了文件夹位置,这个路径没有跟随修改, ...

  6. Primer回顾 标准库类型

    string类型的输入操作符: 1.读取并忽略开头所有的空白字符(如空格,换行符,制表符). 2.读取字符直至再次遇到空白字符,读取终止.   用getline读取整行文本 getline.接受两个参 ...

  7. Google Analytics添加到网站

    把Google Analytics添加到网站的具体方式 https://developers.google.com/analytics/devguides/collection/analyticsjs ...

  8. Parallel类

    Parallel类是对线程很好的一个抽象.该类位于System.Threading.Tasks名称空间中,提供了数据和任务并行性. Parallel类定义了并行的for和foreach的静态方法.Pa ...

  9. MVC4 @helper辅助方法

    Razor提供了一种很方便的语法,可以将view页面中部分内容或部分代码抽取出来,变成一个独立的辅助方法.   eg1: @foreach(var item in Model){ <标签tr&g ...

  10. ms sql server line feed

    多行文本换行: SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ======================================== ...