iOS 8中每次启动时的文档或缓存路径更改

时间:2014-11-18 06:30:24

标签: ios ios8 ios8.1

当我在我的应用程序中下载视频并将其保存在本地缓存/文档路径中并在必要时显示。它在iOS 7中工作,但是avplayer没有在iOS 8及更高版本中显示视频。正如我已经读到的那样,iOS 8中的每次启动都会更改文档/缓存路径。问题是,我必须下载一次视频并在我的应用中多次显示。那么我怎么能一次又一次地到达相同的路径来在应用程序中显示视频。

Here is my code:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// NSLog(@"Document folder: %@", paths);
NSString *documentsDirectory = [paths objectAtIndex:0];
   NSLog(@"Document folder: %@", documentsDirectory);

在日志中,我在每次发布时获得不同的路径。任何帮助,将不胜感激。谢谢

3 个答案:

答案 0 :(得分:15)

我得到了答案。由于绝对路径在每次启动时都在变化,我们可以将数据保存在相对路径上,并在附加绝对路径和相对路径时检索它。

这就是我们如何在相对路径上保存数据:

NSString *documentsDirectory = @"MyFolder";
documentsDirectory = [documentsDirectory stringByAppendingPathComponent:filename];
NSString *relativePath = documentsDirectory;

但是当你读取文件时,你必须使用绝对路径+相对路径:

  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSString *fullCachePath = ((NSURL*)[[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] ).path;
  NSString *fullPath = [fullCachePath stringByAppendingPathComponent:relativePath];  

对于数据库,还仅在相对路径上存储数据。但是,当读取绝对路径并附加来自数据库和读取的相对路径时 它在这里工作。

答案 1 :(得分:7)

应用程序容器或沙箱更改的路径应该是预期的条件。您不应将绝对文件系统路径存储到沙箱目录;而是将路径 relative 存储到该目录,并每次将其附加到NSSearchPathForDirectoriesInDomains的结果。

答案 2 :(得分:0)

建议使用书签来引用文件系统资源。

  

如果要永久保存文件的位置,请使用NSURL的书签功能。书签是一个不透明的数据结构,包含在NSData对象中,用于描述文件的位置。尽管在应用启动之间路径和文件引用URL可能很脆弱,但是即使在移动或重命名文件的情况下,通常也可以使用书签为文件重新创建URL。

     

书签提供对文件系统资源的持久引用。解析书签后,您将获得一个指向资源当前位置的URL。如果用户移动或重命名资源,或者用户重新启动应用程序或重新启动系统,书签与文件系统资源(通常是文件或文件夹)的关联通常会继续起作用。

有关示例代码,请检出File System Programming Guide -> Locating Files Using Bookmarks


如果您想直接使用URL进行向后兼容,我有一个修复代码:

@interface NSURL (App)

/**
 This method try to rebuild a file url relative to application’s home directory.

 If the reciver is not a file url or not in the home directory. The original URL returns.

 @code

 NSString *homePath = NSHomeDirectory();
 // Assume "/Something/Application/B383551F-41C1-4E3D-8EA9-8D76E4AFA919"

 NSURL *test;
 test = [NSURL fileURLWithPath:homePath];
 [test URLByResolvingApplicationDirectoryChange];
 // file://Something/Application/B383551F-41C1-4E3D-8EA9-8D76E4AFA919

 test = [NSURL URLWithString:@"file:///Foo/bar"];
 [test URLByResolvingApplicationDirectoryChange];
 // file:///Foo/bar

 test = [NSURL URLWithString:@"file://Something/Application/12345678-1234-1234-1234-123456789ABC/path.tmp"];
 // file://Something/Application/B383551F-41C1-4E3D-8EA9-8D76E4AFA919/path.tmp

 @endcode
 */
- (nonnull NSURL *)URLByResolvingApplicationDirectoryChange;

@end


@implementation NSURL (App)

- (nonnull NSURL *)URLByResolvingApplicationDirectoryChange {
    if (!self.isFileURL) return self;

    NSString *pathHome = NSHomeDirectory();
    NSString *pathThis = self.path;
    if ([pathThis hasPrefix:pathHome]) {
        return self;
    }

    NSArray<NSString *> *cpHome = pathHome.pathComponents;
    NSMutableArray<NSString *> *cpThis = pathThis.pathComponents.mutableCopy;
    if (cpThis.count < cpHome.count) {
        return self;
    }

    NSInteger i = 0;
    for (i = 0; i < cpHome.count - 2; i++) {
        NSString *hp = cpHome[i];
        NSString *tp = cpThis[i];
        if (![hp isEqualToString:tp]) {
            return self;
        }
    }
    i++;
    NSString *hp = cpHome[i];
    NSString *tp = cpThis[i];
    if (hp.length != tp.length) {
        return self;
    }
    [cpThis replaceObjectAtIndex:i withObject:hp];
    NSString *resolvedPath = [NSString pathWithComponents:cpThis];
    return [NSURL.alloc initFileURLWithPath:resolvedPath];
}

@end