关于IOS文件目录的一点记录
IOS的文件系统面向的是设备上的每个运行的应用程序。为了保证IOS系统的可用性和简单性,IOS设备的终端用户是无法直接访问文件系统的,同时设备上的app与用户一样也是不能随便直接访问文件系统的。IOS的app与文件系统之间的交互被限定在了一个指定的空间或者说是一个目录里,该目录存在于每个App自身沙箱(sandbox)内部。每当在IOS设备上安装一个新的app,IOS的设备上的程序安装器会自动为这个新app提供一个主目录(Home Directory),并将app安装在为其创建的主目录下,此外安装器还会创建为app创建其它几个关键性的目录。所有这些创建的目录组合起来就组成了app的文件系统主视图。因此app对文件系统的操作也仅限定在了以上目录的组合,app可以直接读取这些目录及目录下的任何文件,同时app也可以在指定的任何目录创建自己的文件或写入自己的数据。翻过来说,在这个指定范围之外app不能再访问或创建任何目录和文件。比较特殊的情况是,IOS系统会提供系统接口来允许app访问,例如访问用户存储在设备上的联系方式,相册。但访问这些内容背后所对应的文件操作都是由底层的系统框架来完成。这也是app被称为是一个“沙箱”的原因,在自己的沙箱内,app拥有全面的操作控制权;沙箱之外的东西,在有悖访问规则的前提下,app不能做任何事情。
开启iTunes文件共享
之前对Linux/Unix系统不熟悉(现在其实也不熟悉),对苹果的设备环境,开发体系,硬件特点基本上也处于无知状态,记得起初拿到iPad的时候,一直以为作为移动设备,既然iPad能够与PC端连接,那么就可以把它同时当做是一个移动硬盘来用,可以在PC可iPad之间进行文件的传输,存储,共享。我可以想任意App中放置文件,也可以在PC端像浏览Mac上的文件系统一样,去查看App目录下的内容。后来我发现我错了,根本不是想象中的那样。当iPad连接PC之后,并没有一个设备目录浏览管理界面。其实这也比较苹果系统封闭的风格,苹果希望将用户在苹果设备上的文件都能上传到云端,从而实现可以在多台苹果设备上同步用户数据。
通过在app工程的Info.plist文件中指定UIFileSharingEnabled关键字,并将其值设置为YES。我们可以很方便的打开app与iTunes之间的文件共享。但这种共享有一个前提:App必须将任何所需要共享给用户的文件,都要存放在/Documents目录下,即在app安装时自动创建的app的主目录。下面我们简单说明
在MAC上打开iTunes,在应用程序一栏,默认界面为:
当链接iPad设备后,iTunes界面如下,在面板工具条的右侧会显示iPad当前已连接到Mac上
点击工具条的"iPad"按钮,显示具体的iPad设备信息,如下:
被黄色块盖住的是iPad的设备名称,点击“应用程序按钮”,之后在界面上我们可以看到当前iPad设备的一些相关分类信息,包括存储空间大小,iPad上所安装的IOS版本,是否存在可升级的更高版本的IOS;以及一些iPad设备的备份方式。继续下滚屏,如下界面:
我们看到出现了一个名为“文件共享”的分类。上面很清楚的标明了这个分类的作用是什么,左侧的列表是iPad设备上安装的所有应用程序,右侧列表则是支持iTunes文件共享的App的Documents目录。以苹果的Keynote为例,当我们保存一个文档到iTunes时,Keynotye会讲文件写入到自己的Documents目录下,也就是我们在面板上看到的右侧列表。我们可以直接从MAC上拖文件到该右侧列表,或者从右侧列表选中文件直接拖到MAC上,这样便简单的完成了所谓的iTunes与App的文件共享。可以通过两个按钮完成同样的功能。如图:
我们新建一个简单的DEMO工程来把整个流程走一遍,工程名为FileShareWithITunesDemo
在工程的Info.plist文件中添加支持iTunes文件共享的Key,并将值设为YES,
之后将DEMO工工程发布到iPad设备上,在iTunes的面板上我们可以看到如下图:
现在左侧列表中有了我们的工程对应的APP,接下来在mainStoryboard中添加简单的描述和两个按钮:
之后为两个按钮建立action的outline,代码如下
// 对应第一个按钮- (IBAction)logFilePathInDocumentsDir:(id)sender{NSString*docsDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];NSFileManager*fileManager = [NSFileManagerdefaultManager];NSDirectoryEnumerator*dirEnum = [fileManager enumeratorAtPath:docsDir];NSString*fileName;while(fileName = [dirEnum nextObject]) {NSLog(@"FielName : %@", fileName);NSLog(@"FileFullPath : %@", [docsDir stringByAppendingPathComponent:fileName]) ; }}// 对应第二个按钮- (IBAction)createImageFieldToDocuments:(id)sender{NSFileManager*fileManager=[[NSFileManageralloc] init];NSString*docsDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];NSString*imageFileName = [docsDir stringByAppendingPathComponent:@"myImage.png"] ;UIImage*image = [selfgenerateImage]; [fileManager createFileAtPath:imageFileName contents:UIImagePNGRepresentation(image) attributes:nil] ; }// 创建一个简单的UIImage对象并作为图片文件内容- (UIImage*)generateImage{UIGraphicsBeginImageContextWithOptions(CGSizeMake(320,200),NO,0.0) ;CGContextRefctx =UIGraphicsGetCurrentContext() ;CGRectimageRect =CGRectMake(0.0,0.0,320,200) ; [[UIColorredColor] setFill] ;CGContextFillRect(ctx, imageRect) ;UIImage*image =UIGraphicsGetImageFromCurrentImageContext() ;UIGraphicsEndImageContext() ;returnimage ;}
我们先从MAC简单的拖张图片文件到右侧列表,如图示:
之后点击第一个按钮,输出Documents路径下的所有文件名到控制台
完成之后,点击第二个按钮完成向Documents目录保存文件的功能(即共享文件到iTunes)
至此,简单的流程完毕。