沙盒存储踩坑总结

Path-based URL,File reference URL,String-based path区别

All of the following entries are valid references to a file called MyFile.txt in a user’s Documents directory:

Path-based URL: 
file://localhost/Users/steve/Documents/MyFile.txt

File reference URL: 
file:///.file/id=6571367.2773272/

String-based path:  
/Users/steve/Documents/MyFile.txt

存储文件路径尽可能地使用NSURL(Path-based URL)。因为基于路径的url更容易操作、更容易调试,而且通常是NSFileManager等类的首选。

File reference URL的优点是,在程序运行时,如果用户在Finder中移动文件,任何Path-based URL都会失效,必须更新到新的路径。但是,只要文件在同一磁盘上移动,它的唯一ID就不会改变,任何File reference URL都一直有效。有一点需要注意,系统重启后,File reference URL可能会改变。

  1. NSString 转 NSURL 时,NSString不能包含空格,否则转换得到的NSURL为nil

  2. 使用- (BOOL)moveItemAtURL:toURL: error:使用该方法时,两个URL参数都要确保是fileURL(路径字符串以file:开头),否则会无法move。使用如下方法将NSString转为NSURL:
    [NSURL fileURLWithPath:@"/desktop/."]

  3. 将图片保存到本地后,千万不要保存全路径,比如:/var/mobile/Containers/Data/Application/E710C3F0-844A-420C-91D9-016D06B22A36/Library/Caches/VideoThumbnails/20180821224508.png

只存储自己创建的目录及文件路径即可(上面例子Caches/之后的路径),取数据的时候再通过系统提供的接口(NSHomeDiretory())等方法去拼接完整路径。

原因是每一个App的沙盒路径在运行时会改变,不是唯一确定的值。

File System

An iOS app operating within its own sandbox directory:

屏幕快照 2018-09-25 下午4.10.58.png

Where You Should Put Your App’s Files

To prevent the syncing and backup processes on iOS devices from taking a long time, be selective about where you place files. Apps that store large files can slow down the process of backing up to iTunes or iCloud. These apps can also consume a large amount of a user's available storage, which may encourage the user to delete the app or disable backup of that app's data to iCloud. With this in mind, you should store app data according to the following guidelines:

  • Put user data in Documents/. User data generally includes any files you might want to expose to the user—anything you might want the user to create, import, delete or edit. For a drawing app, user data includes any graphic files the user might create. For a text editor, it includes the text files. Video and audio apps may even include files that the user has downloaded to watch or listen to later.

  • Put app-created support files in the Library/Application support/ directory. In general, this directory includes files that the app uses to run but that should remain hidden from the user. This directory can also include data files, configuration files, templates and modified versions of resources loaded from the app bundle.

  • Remember that files in Documents/ and Application Support/ are backed up by default. You can exclude files from the backup by calling-[NSURL setResourceValue:forKey:error:] using the NSURLIsExcludedFromBackupKey key. Any file that can be re-created or downloaded must be excluded from the backup. This is particularly important for large media files. If your application downloads video or audio files, make sure they are not included in the backup.

  • Put temporary data in the tmp/ directory. Temporary data comprises any data that you do not need to persist for an extended period of time. Remember to delete those files when you are done with them so that they do not continue to consume space on the user’s device. The system will periodically purge these files when your app is not running; therefore, you cannot rely on these files persisting after your app terminates.

  • Put data cache files in the Library/Caches/ directory. Cache data can be used for any data that needs to persist longer than temporary data, but not as long as a support file. Generally speaking, the application does not require cache data to operate properly, but it can use cache data to improve performance. Examples of cache data include (but are not limited to) database cache files and transient, downloadable content. Note that the system may delete the Caches/ directory to free up disk space, so your app must be able to re-create or download these files as needed.

Files, Concurrency, and Thread Safety

Because file-related operations involve interacting with the hard disk and are therefore slow compared to most other operations, most of the file-related interfaces in iOS and macOS are designed with concurrency in mind. Several technologies incorporate asynchronous operation into their design and most others can execute safely from a dispatch queue or secondary thread. Table 1-4 lists some of the key technologies discussed in this document and whether they are safe to use from specific threads or any thread. For specific information about the capabilities of any interface, see the reference documentation for that interface.

屏幕快照 2018-09-25 下午4.14.34.png

It's good habit to alloc/init the file manager for move/copy operations, just in case you decide to add a delegate later.

为App中的文件创建自定义目录

- (NSURL*)applicationDirectory
{
    NSString* bundleID = [[NSBundle mainBundle] bundleIdentifier];
    NSFileManager*fm = [NSFileManager defaultManager];
    NSURL*    dirPath = nil;
 
    // Find the application support directory in the home directory.
    NSArray* appSupportDir = [fm URLsForDirectory:NSApplicationSupportDirectory
                                    inDomains:NSUserDomainMask];
    if ([appSupportDir count] > 0)
    {
        // Append the bundle ID to the URL for the
        // Application Support directory
        dirPath = [[appSupportDir objectAtIndex:0] URLByAppendingPathComponent:bundleID];
 
        // If the directory does not exist, this method creates it.
        // This method is only available in macOS 10.7 and iOS 5.0 or later.
        NSError*    theError = nil;
        if (![fm createDirectoryAtURL:dirPath withIntermediateDirectories:YES
                   attributes:nil error:&theError])
        {
            // Handle the error.
 
            return nil;
        }
    }
 
    return dirPath;
}

拷贝,移动文件或目录

- (void)backupMyApplicationData {
   // Get the application's main data directory
   NSArray* theDirs = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory
                                 inDomains:NSUserDomainMask];
   if ([theDirs count] > 0)
   {
      // Build a path to ~/Library/Application Support/<bundle_ID>/Data
      // where <bundleID> is the actual bundle ID of the application.
      NSURL* appSupportDir = (NSURL*)[theDirs objectAtIndex:0];
      NSString* appBundleID = [[NSBundle mainBundle] bundleIdentifier];
      NSURL* appDataDir = [[appSupportDir URLByAppendingPathComponent:appBundleID]
                               URLByAppendingPathComponent:@"Data"];
 
      // Copy the data to ~/Library/Application Support/<bundle_ID>/Data.backup
      NSURL* backupDir = [appDataDir URLByAppendingPathExtension:@"backup"];
 
      // Perform the copy asynchronously.
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         // It's good habit to alloc/init the file manager for move/copy operations,
         // just in case you decide to add a delegate later.
         NSFileManager* theFM = [[NSFileManager alloc] init];
         NSError* anError;
 
         // Just try to copy the directory.
         if (![theFM copyItemAtURL:appDataDir toURL:backupDir error:&anError]) {
            // If an error occurs, it's probably because a previous backup directory
            // already exists.  Delete the old directory and try again.
            if ([theFM removeItemAtURL:backupDir error:&anError]) {
               // If the operation failed again, abort for real.
               if (![theFM copyItemAtURL:appDataDir toURL:backupDir error:&anError]) {
                  // Report the error....
               }
            }
         }
 
      });
   }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容