将应用无处不在的容器暴露在iOS 8中的iCloud Drive中

hag*_*agi 27 entitlements info-plist icloud icloud-api ios8

我正在开发一个支持iCloud的应用程序,用户可以通过iCloud Drive导入和导出文件.在浏览iCloud Drive时,无论是使用UIDocumentPickerViewController(iOS 8)还是Finder(OS X Yosemite),我都可以看到其他支持iCloud-Drive的应用创建/拥有的目录,例如Automator,Keynote或TextEdit.

我希望我们的应用程序也能在iCloud Drive中公开其无处不在的文档目录,但还未能弄明白.在上述某些应用程序的Info.plist文件中,我发现了这个密钥:

<key>NSUbiquitousContainers</key>
<dict>
    <key>com.apple.TextEdit</key>
    <dict>
        <key>NSUbiquitousContainerIsDocumentScopePublic</key>
        <true/>
        <key>NSUbiquitousContainerSupportedFolderLevels</key>
        <string>Any</string>
    </dict>
</dict>
Run Code Online (Sandbox Code Playgroud)

这些密钥也在这里记录,但我没有找到更广泛主题的任何其他文档.编辑/注意:虽然它不包含我的问题的答案,但文档选择器编程指南是一个有用的资源.

我已经尝试将上述键/值添加到我们的应用程序,但没有看到任何影响.我注意到/尝试过的事情:

  • 对于第三方应用程序,iCloud容器以这种方式构建:iCloud.$(CFBundleIdentifier).我不确定为什么TextEdit只使用纯包标识符,但对于我们的标识符,我尝试了两种方法,即有和没有iCloud.前缀.我还认识到你需要对包标识符进行硬编码(即,不要使用iCloud.$(CFBundleIdentifier)),因为只有PLIST的值似乎在构建时解析,而不是键.

  • 我以编程方式(to <containerPath>/Documents)添加了一个子目录,因此容器不为空.但是,这并不重要,因为所有其他应用程序的目录最初都是空的.

  • 出现在iCloud Drive中的某些Apple应用程序中没有这些条目Info.plist,例如Numbers和Pages.

  • iCloud设置正确,我可以使用返回的URL以编程方式查看ubiquity容器[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];.

  • 我登录到启用了iCloud Drive的iCloud帐户.我可以看到我的iCloud Drive内容UIDocumentPickerViewController.

  • 我使用iOS 8 beta 5模拟器(和Yosemite beta 5来查看Mac上的iCloud Drive目录)(编辑/注意:这同样适用于beta 6)

这就是我的Entitlements文件的样子(仅限相关部分)

<key>com.apple.developer.icloud-container-identifiers</key>
<array>
    <string>iCloud.$(CFBundleIdentifier)</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
    <string>CloudDocuments</string>
</array>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array/>
Run Code Online (Sandbox Code Playgroud)

我已经在Capabilities部分使用Xcode的UI进行了设置.我不明白为什么最后一个键没有条目,但添加<string>iCloud.$(CFBundleIdentifier)</string>没有帮助.相反,它使Xcode在Capabilities UI中抱怨,所以我删除了它.编辑/注意:在Xcode beta 6中,这已经修复,即需要设置无处不在的容器标识符,Xcode可以为您修复.

原始问题:那么......这是一个错误吗?它不起作用吗?我做错了吗?我在发行说明中找不到已知问题.

编辑:

我尝试了两件事:

  • NSUbiquitousContainerName根据Erikmitk的建议,将(可选)键(+值)添加到特定于容器的字典中.

  • 仅将NSUbiquitousContainerIsDocumentScopePublic键/值添加到PLIST根词典而不是容器特定的词典,因为它是在其中一个WWDC示例应用程序中完成的(查找NewBox).

Aar*_*ght 14

我的应用程序遇到了类似的问题.通过执行以下操作,我能够完成这项工作:

  1. 根据此处的文档将NSUbiquitousContainers设置添加到我的Info.plist文件中https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/FileProvider.html.这是相关代码:

    <dict>
        <!-- ... other top-level Info.plist settings ... -->
        <key>NSUbiquitousContainers</key>
        <dict>
            <key>iCloud.com.example.MyApp</key>
            <dict>
                <key>NSUbiquitousContainerIsDocumentScopePublic</key>
                <true/>
                <key>NSUbiquitousContainerSupportedFolderLevels</key>
                <string>Any</string>
                <key>NSUbiquitousContainerName</key>
                <string>MyApp</string>
            </dict>
        </dict>
    </dict>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 重要!然后我将上面的NSUbiquitousContainerSupportedFolderLevels字符串值更改AnyOne

    <key>NSUbiquitousContainerSupportedFolderLevels</key>
    <string>One</string>
    
    Run Code Online (Sandbox Code Playgroud)
  3. 接下来,最后,我不得不改为CFBundleVersion更高版本.我也碰到了CFBundleShortVersionString一个新版本.

构建并运行之后,带有我的应用程序图标的文件夹在iCloud Drive中正确显示!希望这可以帮助!


roo*_*oop 13

编辑Info.plist时,您可能忘了提高软件包版本号?这是WWDC会话#234的要求.

  • 再次,只是试图确保:你是否将`CFBundleVersion`的值更改为更高的数字? (2认同)

hag*_*agi 7

捕获是调用[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];(或使用另一个容器标识符,如果它不是默认容器标识符)至少一次(不是每次启动,但可能是每个版本,或者当更改其中一个相应的PLIST条目时)以初始化目录.我认为这一步需要与捆绑版本号的增加相结合,如roop的回答所示.

我注意到我的问题可能在这方面令人困惑,因为我提到能够使用相关API以编程方式查看文档目录.但是,我稍后从应用程序中删除了该代码,可能在正确设置其余部分之前.我不打算直接写入文档目录,只能通过文档选择器.因此,没有必要获取URL.

如果您只需要一个文档选择器来从/在iCloud Drive或其他应用程序的文档目录中读取/存储文件,则无需调用URLForUbiquityContainerIdentifier:.只有当您希望您的应用程序拥有自己的普遍容器(并且可能在iCloud Drive和文档选择器中公开它)时,原始帖子中提到的步骤和调用URLForUbiquityContainerIdentifier:才是必要的.

*当提到文档目录时,我总是指的是普遍容器中的那个,而不是本地容器.