【问题标题】:Document Or cache Path Changes on every launch in iOS 8在 iOS 8 中每次启动时记录或缓存路径更改
【发布时间】:2015-01-15 06:28:50
【问题描述】:

当我在我的应用程序中下载视频并将其保存在本地缓存/文档路径中并在必要时显示时。它在 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);

在日志中,每次启动时我都会得到不同的路径。任何帮助,将不胜感激。谢谢

【问题讨论】:

  • 您访问的是应用程序的 Documents 目录,而不是缓存目录。
  • 对于缓存,路径也在变化。每次启动时应用程序文件夹更改后路径中的神秘数字。
  • 如果我使用 NSCachesDirectory,这就是我在日志中得到的内容。这里的神秘数字也在发生变化。 /Users/mantavya/Library/Developer/CoreSimulator/Devices/76A9B09C-434E-4C29-879D-119556A10AA9/data/Containers/Data/Application/34093128-B643-4030-B36A-350B3110C12C/Library/Caches
  • 我也注意到了这种行为。但是在官方文档中找不到任何参考。

标签: ios ios8 ios8.1


【解决方案1】:

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

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

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];  

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

【讨论】:

  • 您在保存文件时不需要指定完整路径,以便您知道它的去向吗?似乎最佳做法是在阅读和写作时两次生成完整路径。这就是最终为我工作的原因。
  • 当我尝试保存在相对路径中时,它不会保存数据。它失败了。你能指导我保存在documentsDirectory上吗?
  • 你可以像上面2种方法一样存储。 “文件夹名称”中的相对路径并保持原样。也照原样复制下一部分。
  • 你能添加保存和检索文件的代码吗,考虑文件是图像。
【解决方案2】:

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

【讨论】:

  • 你能给我一些链接吗?
  • 我必须在本地设备或模拟器上存储一些视频文件。
【解决方案3】:

推荐使用书签来引用文件系统资源。

如果您想永久保存文件的位置,请使用 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

【讨论】:

    猜你喜欢
    • 2022-07-21
    • 2014-12-11
    • 2014-11-11
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多