IOS 8:捆绑path的变化

我有一个iOS应用程序,它将文件的绝对path存储在数据库和生成的html文档中。 我只是最近更新我的iPhone到iOS 8,现在当我运行应用程序似乎应用程序安装在不同的目录中,每重新编译。 例如,在第一个构build/运行[[NSBundle mainBundle] bundlePath]在下一个构build/运行时返回不同的东西。 到底是怎么回事? 这是苹果的新function吗?

更新:创build了一个错误报告

代码示例:

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

#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设置为网页的目录,并通过绝对文件path访问束资源。 现在文件path在每次更新时都会改变,这已经被破坏。 我尝试创build捆绑资源的符号链接,但是也无法执行后续更新。

请参阅Apple的技术说明2406

突破的变化是

从iOS 8开始,文档和库目录不再是应用程序包的兄弟姐妹。

不要将完整path/ URL存储到您的文档。 保存文件名并始终使用build议的方法生成完整path/ URL。

获取DocumentsDirectory URL

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

然后你得到的URL的path,并追加文件的名称,以生成完整的path。

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

从iOS 8发行说明:

应用程序容器的文件系统布局在磁盘上已更改。 使用NSSearchPathForDirectoriesInDomains函数或URLForDirectory:inDomain:appropriateForURL:create:error:方法,而不是依赖硬编码的目录结构。 请参阅文件系统编程指南中的 访问文件和目录 。

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

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

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

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

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

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

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

使用书签查找文件

本节之前几行是这样的文字:

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

再见。

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

/ var / mobile / Containers / Data / Application / 4FFCE2CB-580D-409A-90CB-EF2B8A1FB653 / Library / var / mobile / Containers / Data / Application / B038B2DA-F85D-4E18-A5F1-8635834EC454 / Library

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

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

结果是一样的。 每个构build和运行的不同path。