ios 8:捆绑路径更改

时间:2014-09-17 07:09:15

标签: ios objective-c

我有一个iOS应用程序,用于存储数据库和生成的html文档中文件的绝对路径。我刚刚将我的iPhone更新到iOS 8,现在当我运行应用程序时,似乎应用程序安装在每个重新编译的不同目录中。例如,在第一次构建/运行[[NSBundle mainBundle] bundlePath]上,在下一次构建/运行时返回不同的内容。到底是怎么回事?这是Apple的新功能吗?

更新:已创建错误报告

代码示例:

如果我在多个构建/运行中运行以下行,那么每次都会得到不同的结果。

#define kOLD_PATH @"oldPath"
NSString* newPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString* oldPath = [[NSUserDefaults standardUserDefaults] objectForKey:kOLD_PATH];

NSLog(@"New Path: %@", newPath);
NSLog(@"Old Path: %@", oldPath);
NSLog(@"Result: %@", [oldPath isEqualToString:newPath] ? @"Same" : @"Changed");

[[NSUserDefaults standardUserDefaults] setObject:newPath forKey:kOLD_PATH];
[[NSUserDefaults standardUserDefaults] synchronize];

输出在多次运行中看起来像这样

New Path: /var/mobile/Containers/Data/Application/4FFCE2CB-580D-409A-90CB-EF2B8A1FB653/Library
Old Path: /var/mobile/Containers/Data/Application/B038B2DA-F85D-4E18-A5F1-8635834EC454/Library
Result: Changed

完全披露:在我的应用中,用户导入包含资源的网页(ePub)。资源与网页一起存储。该网页还访问属于应用程序包的资源。为了实现这一点,当我加载网页时,基本URL被设置为网页所在的目录,并且通过绝对文件路径访问包资源。现在,每次更新时文件路径都会发生变化。我尝试创建捆绑资源的符号链接,但也无法进行后续更新。

4 个答案:

答案 0 :(得分:18)

在iOS 8中,应用容器的文件系统布局已更改。应用程序及其内容不再存储在一个根目录中。

来自iOS 8发行说明:

  

应用程序容器的文件系统布局已在磁盘上更改。宁   而不是依靠硬编码的目录结构,使用   NSSearchPathForDirectoriesInDomains功能或   URLForDirectory:inDomain:appropriateForURL:create:error:方法   NSFileManager课程。请参阅Accessing Files and Directories中的File System Programming Guide

这不是错误。确保使用推荐的API(来自上面的引用),你就不会有问题。

因此,如果您尝试访问添加到项目中的捆绑资源,则可以使用:

[[NSBundle mainBundle] pathForResource:@"resourceName" ofType:@"extension"];

但是如果你想使用放在文档目录中的东西,你可以使用:

[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"resourceName.extension"];

答案 1 :(得分:8)

Refer Technical Note 2406 by Apple

突破性变化是

  

从iOS 8开始,Documents和Library目录都没有   申请人捆绑的兄弟姐妹。

不要将完整路径/ URL存储到您的文档中。存储文件名,并始终使用推荐的方法生成完整路径/ URL。

获取DocumentsDirectory网址

// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

然后你从url获取路径并附加文件名以生成完整路径。

答案 2 :(得分:3)

不知道你是否解决了问题,但这个链接可能就是答案。

https://developer.apple.com/library/prerelease/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/AccessingFilesandDirectories/AccessingFilesandDirectories.html#//apple_ref/doc/uid/TP40010672-CH3-SW10

使用书签查找文件

页面中此部分之前的几行是此文:

"重要提示:虽然在您的应用运行时可以安全地使用它们,但是在应用启动之间存储和重复使用文件引用URL是不安全的,因为如果系统重新启动,文件ID可能会更改。如果要在启动应用程序之间持久存储文件的位置,请按照使用书签查找文件中所述创建书签。"

再见。

答案 3 :(得分:2)

我认为每个构建和运行的不同路径是iOS模拟器中发生的事情的预期方式。这不是问题。

的/ var /移动/容器/数据/应用/ 4FFCE2CB-580D-409A-90CB-EF2B8A1FB653 /库 的/ var /移动/容器/数据/应用/ B038B2DA-F85D-4E18-A5F1-8635834EC454 /库

我发现即使你使用推荐的方式

- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
}

结果相同。每个构建的不同路径&运行