我有一个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被设置为网页所在的目录,并且通过绝对文件路径访问包资源。现在,每次更新时文件路径都会发生变化。我尝试创建捆绑资源的符号链接,但也无法进行后续更新。
答案 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)
不知道你是否解决了问题,但这个链接可能就是答案。
使用书签查找文件
页面中此部分之前的几行是此文:
"重要提示:虽然在您的应用运行时可以安全地使用它们,但是在应用启动之间存储和重复使用文件引用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];
}
结果相同。每个构建的不同路径&运行