将文件保存到 icloud 驱动器

Vla*_*ala 12 ios swift icloud-drive

我正在尝试将文件保存到 icloud 驱动器。我要使用简单版本,不让用户选择保存文件的位置,我只是将其保存在 icloud 驱动器的根目录中。这是我正在使用的代码:

func exportToFiles() {
    for page in pages {
            let filename = getDocumentsDirectory().appendingPathComponent((page.title ?? "Untitled") + ".png")
        if let image = exportImage(page: page, dpi: 300) {
            if let data = image.pngData() {
                try? data.write(to: filename)
            }
        }
    }
}

func getDocumentsDirectory() -> URL {
    let driveURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
    return driveURL!
}
Run Code Online (Sandbox Code Playgroud)

我的文件中有这个Info.plist

<key>NSUbiquitousContainers</key>
<dict>
        <key>iCloud.com.mysite.myapp</key>
        <dict>
                <key>NSUbiquitousContainerIsDocumentScopePublic</key>
                <true/>
                <key>NSUbiquitousContainerName</key>
                <string>myapp</string>
                <key>NSUbiquitousContainerSupportedFolderLevels</key>
                <string>Any</string>
        </dict>
</dict>
Run Code Online (Sandbox Code Playgroud)

在用户界面中,它看起来像是有效的,因为在我点击按钮后有轻微的停顿。但当我查看我的文件时,什么也没有。我究竟做错了什么?

iUr*_*rii 10

您必须检查并创建“文档”文件夹,并且处理错误也是一个很好的做法:

if let containerUrl = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents") {
    if !FileManager.default.fileExists(atPath: containerUrl.path, isDirectory: nil) {
        do {
            try FileManager.default.createDirectory(at: containerUrl, withIntermediateDirectories: true, attributes: nil)
        }
        catch {
            print(error.localizedDescription)
        }
    }
    
    let fileUrl = containerUrl.appendingPathComponent("hello.txt")
    do {
        try "Hello iCloud!".write(to: fileUrl, atomically: true, encoding: .utf8)
    }
    catch {
        print(error.localizedDescription)
    }
}
Run Code Online (Sandbox Code Playgroud)


bru*_*337 8

要在 2022 年中期使用 SwiftUI、Swift 5、Xcode 13.2.1、iOS 15.2 更新此内容:

  • 在 iOS 应用程序目标的“签名和功能”选项卡下,单击“+ 功能”按钮。在出现的对话框中,向左向下滚动以找到“iCloud”并双击它。
  • 回到“签名和功能”下,将出现一个新部分。检查“iCloud 文档”并在其下方查找“容器”列表。在第一个条目中,复制并粘贴“捆绑包标识符”(同一窗格顶部附近)中的值。编辑容器条目,使其采用iCloud.domain.orgName.appName格式。例如,如果您的包标识符是foo.bar.bazApp,则容器列表中的第一个条目应该是iCloud.foo.bar.bazApp。执行此操作后,应检查第一个条目。
  • 如果您没有 .plist 文件,则需要创建一个。它应该是导航器窗格中的第一个或第二个文件,其名称应采用bazApp--iOS--Info的形式。单击它进行编辑。它应该看起来像这样 - 请注意,容器名称的最后一部分需要与下面的完全NSUbiquitousContainerName匹配。继续 iCloud.foo.bar。bazApp示例在这里:
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>NSUbiquitousContainers</key>
  <dict>
      <key>iCloud.foo.bar.bazApp</key>
      <dict>
          <key>NSUbiquitousContainerIsDocumentScopePublic</key>
          <true/>
          <key>NSUbiquitousContainerName</key>
          <string>bazApp</string>
          <key>NSUbiquitousContainerSupportedFolderLevels</key>
          <string>Any</string>
      </dict>
  </dict>
</dict>
</plist>
Run Code Online (Sandbox Code Playgroud)
  • 在您的实际应用程序代码中,使用上面列出的示例来编写测试文件。
  • 如果您对 .plist 文件进行了任何更改,请在 iOS 目标的“常规”选项卡下的“身份”部分中增加版本和构建字段。

如果您已正确设置所有内容,则在手机或模拟器的“文件”应用程序 > iCloud Drive 中,您应该会看到一个包含应用程序名称和应用程序图标的新文件夹,就像任何其他特定于应用程序的 iCloud 文件夹一样。里面应该是你的新测试文件。如果像我一样,您没有NSUbiquitousContainerName在 .plist 中准确输入值,您的代码将运行,但测试文件只会写入“设置”>“[您的姓名]”>“iCloud”>“管理存储”>“[您的应用程序名称]”>“文档” 。这里的其他一些答案建议NSUbiquitousContainerName可以是您喜欢的任何名称,但我的经验是它必须与容器名称的结尾部分完全匹配。