【问题标题】:Cannot programmatically access some files in iCloud Drive无法以编程方式访问 iCloud Drive 中的某些文件
【发布时间】:2019-12-09 03:41:55
【问题描述】:

这可能是我的解决方案

我怀疑我的问题是因为我没有打开“iCloud”功能,但因为我有一个免费的开发者帐户,所以我不能这样做。

如果打开“iCloud”功能是解决方案,是否还有一些说明这一点的文档

我只找到了documentation regarding "CloudKit",它从不指代“iCloud Drive”。

在这个website 上有一些指向其他文档的链接。


问题陈述

iCloud Drive 中的文件夹结构:

  • “TestApp”(iCloud Drive 中应用名称的目录)
    • “测试”(目录)
      • “testFile 1.txt”(使用UIDocumentBrowserViewController打开文档)
      • “testFile 2.txt”(尝试以编程方式打开文档)

如果我使用UIDocumentBrowserViewController (documentation) 打开目录中的文档,我可以毫无问题地调用document.open(...)documentUIDocument 的子类)。但是,如果我想以编程方式访问文件夹中的其他文件,则会出现错误:

Error Domain=NSCocoaErrorDomain Code=257 "无法打开文件“testFile 2.txt”,因为您没有查看权限。" UserInfo={NSFilePath=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/TestApp/test/testFile 2.txt, NSUnderlyingError=0x2829d20a0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not allowed"}}

我如何尝试以编程方式访问“testFile 2.txt”

当用户打开“testFile 1.txt”时,我得到它的 url,即:

"file:///private/var/mobile/Library/Mobile%20Documents/com~apple~CloudDocs/TestApp/test/testFile%201.txt"

现在我正在使用以下代码尝试访问“testFile 2.txt”(另请参见内联 cmets):

// I get this url from the delegate method `UIDocumentBrowserViewControllerDelegate.documentBrowser(_:didPickDocumentsAt:)`
let file1URL = // ...
let file2URL = file1URL
    .deletingLastPathComponent()
    .appendingPathComponent("testFile 2")
    .appendingPathExtension("txt")

let success = file2URL.startAccessingSecurityScopedResource() // returns `false`

TestDocument(fileURL: file2URL).open{ success in
    print(success) // prints `false` and see ERROR above
}

// checking existence
let fm = FileManager.default
fm.isUbiquitousItem(at: file1URL)    // returns `true`
fm.fileExists(atPath: file1URL.path) // returns `true`
fm.isUbiquitousItem(at: file2URL)    // returns `false`
fm.fileExists(atPath: file2URL.path) // returns `false`

如您所见,文件管理器的“testFile 2.txt”“不存在”。

【问题讨论】:

    标签: ios icloud icloud-drive


    【解决方案1】:

    考虑一个类比:

    你是别人家的客人。你要一些水。他们从冰箱里拿出一瓶给你。

    这是否意味着他们允许您去冰箱拿啤酒或葡萄酒?不。这是否意味着允许搜索他们冰箱的内容以查看他们有什么?不,你能明确要求啤酒吗?是的。他们能说“不”吗?也可以。

    同样,您的应用是用户设备上的访客。它在沙箱中运行。它需要请求许可才能访问沙箱外的资源。

    在文件访问的情况下,它需要对要访问的文件的特定权限。它不能只创建文件路径并访问文件;用户需要专门授予访问文件的权限。

    在这种情况下,权限是通过UIDocumentBrowserViewController 授予的。您的应用没有被授予对testFile 2.txt 的访问权限,因此iOS 的行为就像该文件不存在一样。如果您想访问该文件,您必须明确询问。

    应用无法访问用户文件的完整内容。

    【讨论】:

    • 感谢您的精彩比喻!但是我认为应用程序目录(此处为“TestApp”)也在沙箱内!?那么所有 iCloud Drive 文件都在应用沙箱之外吗?
    • 所有 iCloud 文件(以及保管箱文件和 OneDrive 文件以及文件提供商提供的任何文件)都在沙箱之外。当您使用文档浏览器时,iOS 会授予您对该文件的权限;您必须使用startAccessingSecurityScopedResource 来行使该权限。
    • 您在 iCloud Drive 中创建了目录“TestApp”。如果您愿意,您可以将目录命名为“Fridge”,并且如果您获得许可,仍然可以访问它。没有隐式访问仅仅因为应用程序和文件夹具有相同的名称
    • 你也可以在你的答案中写下吗?我仍然有点困惑:见developer.apple.com/library/archive/documentation/General/… 他们只提到“iCloud Containers”。这与“TestApp”目录相同吗?如果是,则必须激活 iCloud 功能。
    • 不,iCloud containers 是一个私有存储,应用可以使用它在用户设备之间同步文档和键值存储。 iCloud 容器对应用程序可见,无需任何其他权限,因为它们被视为应用程序的数据。用户使用files app看不到iCloud容器的内容,也无法直接修改内容
    猜你喜欢
    • 2018-04-26
    • 2017-10-11
    • 2016-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-03
    相关资源
    最近更新 更多