【问题标题】:File URL fails to resolve from bookmark after app restart/rebuild应用程序重新启动/重建后,文件 URL 无法从书签中解析
【发布时间】:2020-10-13 06:20:09
【问题描述】:

我正在存储文件 URL,以便在 iOS 应用程序的后续运行中检索它们。 URL 是由用户在其设备上选择本地或 iCloud 文件生成的。给定的 URL 似乎指向 Documents 中的一个文件,但实际上并不存在。

我有以下代码来解析书签中的 URL:

BOOL isBookmarkStale = false;
NSError* error = nil;

auto nsURL = [NSURL URLByResolvingBookmarkData:bookmark
                                       options:NSURLBookmarkResolutionWithoutUI
                                 relativeToURL:nil
                           bookmarkDataIsStale:&isBookmarkStale
                                         error:&error];

书签是用

创建的
if ([nsURL startAccessingSecurityScopedResource])
{

    NSError* error = nil;

    NSData* securityScopedBookmark = [nsURL bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
                                             includingResourceValuesForKeys:nil
                                                              relativeToURL:nil
                                                                      error:&error];

    [nsURL stopAccessingSecurityScopedResource];
}

我已经通过检查最后一个已知路径来验证存储的书签包含正确的 URL

NSDictionary *values = [NSURL resourceValuesForKeys:@[NSURLPathKey]
                                   fromBookmarkData:static_cast<NSData*> (bookmarkData)];

NSString *path = [values objectForKey:NSURLPathKey];

这里的路径包含文件的最后一个 URL。我正在测试的本地文件中的 URL 字符串如下所示:/private/var/mobile/Containers/Data/Application/3BFEA0FB-AA84-4CFB-90E5-3535FA14738E/Documents/SomeFile.mp3

这似乎在应用程序运行时有效。但在重新启动或重建应用程序(调试构建)后,尝试从存储的书签中解析 URL 失败,并显示 NSCocoaErrorDomain Code=4 和消息“文件不存在”。

【问题讨论】:

  • 我注意到模拟器在您运行它时会不断更改您的应用程序的 URL。这不会在设备上发生,但要在模拟器上进行测试,您需要存储相对于应用的主目录或文档目录的 URL。
  • 好的 @skaak 感谢您的提示。我正在设备上运行,因为模拟器在选择文件时不起作用,可能是由于您提到的问题
  • 是的,要返回 sim,您需要使 URL 相对。只有.../Documents/... 部分是稳定的,但你会得到正常的方式。我会为此发布一个答案,,,

标签: ios objective-c nsurl


【解决方案1】:

是的,绝对路径可能会改变,所以使用相对路径。 只需将您想要的部分保存在 Documents 之后即可。

let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first

这将是一个可选的 URL(因为 .first),所以你可能想要

if let documentsDirectory

guard let documentsDirectory 使其成为非可选的。

然后你可以做documentsDirectory.appendingPathComponent(pathComponent: SomeFile.mp3)

【讨论】:

  • 问题似乎是文件本身在书签中存储的路径中不存在。我尝试存储相对路径,但它不起作用。我的假设是提供的 URL 不是真实文件,而是会话期间可从应用程序访问的某种临时内容。
【解决方案2】:

要获取用户文档的 URL,请使用

[NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject

这将在设备上保持不变,但在模拟器上的运行之间会发生变化。所以你需要让你的 URL 与此相关,以便在 sim 中进行测试。

【讨论】:

  • 请更新此答案以使其有意义。想象一下有人要阅读这个问题和这个答案(没有 cmets)。这个人不会知道你对获取文档的 URL 然后从那里构建等是什么意思。
  • 是的,完全同意。我最初想将其发布到评论中,但它变得太笨拙了,所以我只是将其发布为答案。但我会尽快按照您的建议进行修复。
猜你喜欢
  • 1970-01-01
  • 2014-09-14
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-29
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多