美文网首页iOS资料iOS开发那些事程序员
盗梦空间 | iOS沙盒开发指南

盗梦空间 | iOS沙盒开发指南

作者: 溪石iOS | 来源:发表于2016-06-05 21:52 被阅读627次

    试想有这么一款游戏:里面有山有水,有车有房,有铁轨公路,你在里面上天入海,杀人放火,驾飞机,开坦克,你似乎拥有整个世界,而另一个玩家也有同样的幻觉;对于游戏主机来说,不过是给你们每人一个“盒子”,一个微观盆景罢了,你的胡作非为,对其他玩家不会造成任何影响。这便是沙盒,一种文件访问权限的隔离机制。

    每个应用都有相同的文件目录,对自己目录下的修改不会对其它应用造成影响。
    换句话说,应用也不能通过相同的路径访问到其它应用的文件,这与我们在PC机下常用文件共享有很大的差别。


    沙盒中各个文件夹的差别

    每个应用默认都有以下文件夹,如下图所示:



    每个目录的功能有以下差别:


    每个文件夹的“能力”各有差别,以适用不同的使用场景,Document/适合用户生成的,需要备份、共享的数据,如文件工具生成的Doc类文档。
    Library/适合后台记录值,但用户无需看到的数据,比如服务器同步数据,缓存数据库文件等。

    根目录新建其它文件夹会怎么样?
    可以建任意文件夹及文件,但备份等行为并不保证,比如iOS8下无法在根目录建立文件夹,iOS9却可以,不要依赖这种不确定的系统行为。


    如何查看沙盒文件

    查看模拟器沙盒:

    1. APP工程里加入以下代码:
    NSString *homeDirectory = NSHomeDirectory();
    NSLog(@"path:%@", homeDirectory);
    

    控制台输出的路径如下

    /Users/[用户名]/Library/Developer/CoreSimulator/Devices/04D49FFD-11F6-4A1E-BE74-D7C3A1AD1D40/data/Containers/Data/Application/20DE6878-D29E-431C-BAC1-78B4A85F51D3/Documents
    

    20DE6878-D29E-431C-BAC1-78B4A85F51D3 这串字母数字

    每次应用启动都会变化,小心不要被先前的路径误导

    1. 打开Finder



      使用Finder打开路径
      模拟器沙盒中的目录

    查看真机沙盒

    打开Xcode设备管理器
    选择齿轮图标 选择Show Container
    显示的真机沙盒

    编程访问各文件夹的方法

    访问Home

    见上文 查看模拟器沙盒

    访问Document

    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0]; 
    NSLog(@"The document's path:%@", documentPath);
    

    这里返回的数组在iOS平台上总是只有一个对象

    更换以上NSDocumentDirectory的枚举值,可获得其它沙盒目录路径

    NSLibraryDirectory //.../Library/
    NSCachesDirectory //.../Library/Caches/
    
    NSString *tempPath = NSTemporaryDirectory(); //.../tmp/
    NSLog(@"tempPath:%@", tempPath);
    

    获得安装包中的文件路径

    NSString *imagePath = [[NSBundle mainBundle] pathForResource:@”apple” ofType:@”png”];
    

    突破沙盒

    1. 在程序间共享文档

    可以通过UIDocumentInteractionController

    将文件分享给其它应用:

    - (void)shareFile { 
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"我的图片" ofType:@"jpeg"];  //创建实例
        UIDocumentInteractionController *documentController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];  //设置代理 
        documentController.delegate = self; 
        BOOL canOpen = [documentController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
        if (!canOpen) { 
            NSLog(@"沒有程序可以打开要分享的文件"); 
        }
    }
    

    注册自己能打开的文件:

    这需要在程序的Info.plist文件中添加CFBundleDocumentTypes键, 它是一个dictionary数组,每个dictionary表示了一个指定的文档类型。
    数组中的每个 dictionary 可能包含以下键:

    CFBundleTypeName
    指定文档类型名称。

    CFBundleTypeIconFiles
    是一个数组,包含多个图片文件名,用于作为该文档的图标。

    LSItemContentTypes
    是一个数组,包含多个UTI类型的字符串。UTI
    类型是本文档类型(组)所包含的文件类型。

    LSHandlerRank
    表示应用程序是“拥有”还是仅仅是“打开”这种类型而已。

    一个plist文件中的例子:

    <dict>
    
    <key>CFBundleTypeName</key>
    
    <string>My File Format</string>
    
    <key>CFBundleTypeIconFiles</key>
    
    <array>
    
    <string>MySmallIcon.png</string>
    
    <string>MyLargeIcon.png</string>
    
    </array>
    
    <key>LSItemContentTypes</key>
    
    <array>
    
    <string>com.example.myformat</string>
    
    </array>
    
    <key>LSHandlerRank</key>
    
    <string>Owner</string>
    
    </dict>
    

    响应其它应用的打开文件请求:

    实现application:didFinishLaunchingWithOptions:
    方法中获得该文件的信息,而不是applicationDidFinishLaunching
    如果你的应用程序处于活跃状态,此时application:didFinishLaunchingWithOptions:
    方法是不会被调用的。需要实现application:openURL:options:
    方法

    相关文章

      网友评论

      本文标题:盗梦空间 | iOS沙盒开发指南

      本文链接:https://www.haomeiwen.com/subject/cjxqdttx.html