如何在不使用 Xcode 的情况下将 iCloud Documents 功能添加到我的应用程序?

Posted

技术标签:

【中文标题】如何在不使用 Xcode 的情况下将 iCloud Documents 功能添加到我的应用程序?【英文标题】:How can I add iCloud Documents capabilities to my application without using Xcode? 【发布时间】:2017-05-12 09:14:08 【问题描述】:

当执行以下两行之一时,我的应用程序崩溃并显示“应用程序初始化文档选择器缺少 iCloud 权利”:

UIDocumentPickerViewController* documentPicker =
  [[UIDocumentPickerViewController alloc]
    initWithDocumentTypes:@[@"public.data"]
                   inMode:UIDocumentPickerModeImport];

UIDocumentMenuViewController *documentMenu =
  [[UIDocumentMenuViewController alloc]
    initWithDocumentTypes:@[@"public.data"]
                   inMode:UIDocumentPickerModeImport];

Document Picker Programming Guide 声明“在您的应用可以使用文档选择器之前,您必须在 Xcode 中打开 iCloud 文档功能。”

但是,我的应用程序不是使用 Xcode 构建的:它是使用第三方工具(跨平台工具包,Marmalade)构建的,所以我不能这样做。

应该仍然可以手动打开此应用的 iCloud 文档功能 —  iCloud 中的开关只是自动执行此过程 — 但我尝试这样做并没有解决崩溃问题。

到目前为止我已经尝试过什么

Xcode 显示打开 iCloud 时执行的步骤:

    将“iCloud”权利添加到您的 App ID 将“iCloud 容器”权利添加到您的 App ID 将“iCloud”权利添加到您的权利文件中 链接 CloudKit.framework

我还找到了 Apple 的 Entitlements Troubleshooting TechNote,其中描述了可以用来检查以下步骤是否正确执行的步骤。

我已在我的 App ID 上启用 iCloud:

我不确定这是否需要使用文档选择器的简单导入和导出操作,但我还设置了一个id为iCloud.com.[company].[app]的iCloud容器。

我已生成包含 iCloud 权利的更新配置文件:

我使用以下命令检查了下载的配置文件:

security cms -D -i /path/to/iosTeamProfile.mobileprovision

它包括以下条目:

<key>com.apple.developer.icloud-services</key>
<string>*</string>
<key>com.apple.developer.icloud-container-environment</key>
<array>
  <string>Development</string>
  <string>Production</string>
</array>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
  <string>iCloud.com.[company].[app]</string>
</array>
<key>com.apple.developer.icloud-container-development-container-identifiers</key>
<array>
  <string>iCloud.com.[company].[app]</string>
</array>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
  <string>iCloud.com.[company].[app]</string>
</array>

Marmalade 使用此配置文件为应用生成权利文件。

我已经使用以下命令检查了生成的权利:

codesign -d --ent :- [App.app]

它给出以下输出:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>application-identifier</key>
  <string>[team-id].com.[company].[app]</string>
  <key>aps-environment</key>
  <string>development</string>
  <key>com.apple.developer.icloud-container-development-container-identifiers</key>
  <array>
    <string>iCloud.com.[company].[app]</string>
  </array>
  <key>com.apple.developer.icloud-container-environment</key>
  <array>
    <string>Development</string>
    <string>Production</string>
  </array>
  <key>com.apple.developer.icloud-container-identifiers</key>
  <array>
    <string>iCloud.com.[company].[app]</string>
  </array>
  <key>com.apple.developer.icloud-services</key>
  <string>*</string>
  <key>com.apple.developer.team-identifier</key>
  <string>[team-id]</string>
  <key>com.apple.developer.ubiquity-container-identifiers</key>
  <array>
    <string>iCloud.com.[company].[app]</string>
  </array>
  <key>com.apple.developer.ubiquity-kvstore-identifier</key>
  <string>[team-id].*</string>
  <key>get-task-allow</key>
  <true/>
  <key>keychain-access-groups</key>
  <array>
    <string>[team-id].com.[company].[app]</string>
  </array>
</dict>
</plist>

但是,每当调用函数时,应用程序仍然会崩溃。

我还找到了this old guide to setting up iCloud in Marmalade apps。大多数步骤似乎不再是必要/可能的,但我按照建议将 application-identifier 键添加到我的 Info.plist。

我还需要做什么才能将 iCloud Documents 功能添加到我的应用程序中?

【问题讨论】:

你是否添加了隐私消息,因为iOS10你必须征求用户的许可,所以在原生应用中你在.plist中添加隐私声明,这是告诉用户为什么你需要访问权限的消息跨度> @SeanLintern88 我没有,但我目前正在使用 iOS 8 的设备上进行测试。所以我认为这不是问题吗?此外,我在this list 中找不到用于调用文档选择器或使用 iCloud 的隐私目的字符串。您指的是哪个 plist 键? @Rich,同样的问题。你解决了吗? @Giorgio 到目前为止还没有运气。如果你修复它,请发布答案! @Giorgio 请参阅下面的回答,了解我们最终如何解决此问题。 【参考方案1】:

Marmalade 通过复制配置文件中的“权利”dict 来生成 .xcent 权利文件,用于签署应用程序。

问题是由与undocumented 键关联的值引起的:

<key>com.apple.developer.icloud-services</key>
<string>*</string>

这在配置文件中显示为有效,但在登录应用时无效。将生成的 .xcent file 中的这些元素替换为以下内容,然后重新签署应用程序可解决问题:

<key>com.apple.developer.icloud-services</key>
<array>
  <string>CloudDocuments</string>
</array>

(注意,如果您还使用 CloudKit,您还需要在 array 中添加一个 CloudKit string。)

实际上,我们通过编辑 Marmalade 的 sign_app.py 脚本来修复此问题,以便在签署应用程序时使用预先准备的 .xcent 文件(从我们使用 Xcode 构建的功能应用程序的 DerivedData 目录复制而来):

在文件/Applications/Marmalade.app/Contents/s3e/deploy/plugins/iphone编辑第557行:

cmd += ['--entitlements', xcentfile.name]

...将xcentfile.name 替换为预先准备好的.xcent 文件的路径。

【讨论】:

以上是关于如何在不使用 Xcode 的情况下将 iCloud Documents 功能添加到我的应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

在不安装 Xcode 的情况下将 GCC 安装到 Mac OS X Leopard

在不启动应用程序的情况下将应用程序从 Xcode 部署到设备

在不知道编码类型的情况下将 NSData 转换为 NSString

如何在不使用 InterfaceBuilder 的情况下将 UISwitch(切换开关)添加到 UIToolBar

如何在不使用任何付费工具的情况下将 dbf 文件导入 mysql?

如何在不使用 ToString() 的情况下将 Int 转换为 C# 中的字符串?