【问题标题】:iOS UI test target is missing entitlement icloud-servicesiOS UI 测试目标缺少权利 icloud-services
【发布时间】:2019-09-02 12:36:41
【问题描述】:

我有一个使用 iCloud 的应用程序。这工作正常。

我现在尝试编写一个 UI 测试,首先检查 iCloud 帐户是否可访问,即用户是否登录到 iCloud 并且为应用启用了 iCloud。

为此,我尝试调用(导入了 CloudKit)

let container = CKContainer(identifier: kICloudContainerID)
container.accountStatus() { (status, error) in
  // …
}  

但是,当我尝试访问 CKContainer(第一行)时,我得到了错误

The application is missing required entitlement com.apple.developer.icloud-services
(null)

当然,我的应用设置了 iCloud 权利,但无法为测试目标设置此类权利。

我已阅读this post。建议的解决方案(禁用断点、切换 iCloud 功能、清除代码签名权利)不起作用。

知道如何解决这个问题吗?

编辑:

为了进行测试,我创建了一个包含 UI 测试的新单视图应用程序。
在应用目标中,我只启用了 CloudKit:

在app delegate中,我导入了CloudKit,并访问了CKContainer

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let container = CKContainer(identifier: "iCloud.com.zeh4soft.EntitlementUITest")
    return true
}  

这行得通。

在 UI 测试中,我还导入了 CloudKit,并添加了同一行:

func testExample() {
  let container = CKContainer(identifier: "iCloud.com.zeh4soft.EntitlementUITest")
}  

这不起作用,但会出现同样的错误:

【问题讨论】:

    标签: xcode cloudkit xcode-ui-testing code-signing-entitlements


    【解决方案1】:

    我联系了 Apple,他们找到了适用于设备的解决方案,但没有找到适用于模拟器的解决方案。
    我做了以下步骤:

    在 Xcode 中设置一个全新的 Single View App 项目并包含 UI 测试。称之为“EntitlementUITest”。 这将在项目导航器中创建一个名为“EntitlementUITestUITests”的文件夹。

    在此文件夹中选择“EntitlementUITestUITests.swift”。
    有一个函数testExample()。在这个函数中添加一行

        let _   = CKContainer(identifier: "iCloud.com.yourid.EntitlementUITest")
    

    yourid 是例如您的公司名称。
    如果项目未按以下规定准备,则此语句会导致运行时错误。

    在项目导航器中选择项目。
    这将显示一个包含项目和目标的附加窗格。
    有 2 个目标:主目标“EntitlementUITest”和 UI 测试目标“EntitlementUITestUITests”。
    选择主要目标“EntitlementUITest”。
    在窗格右侧窗口的顶部栏中,选择“功能”。您将看到您可以选择 iCloud 使用情况。

    现在选择测试目标“EntitlementUITestUITests”。顶部栏现在没有“功能”。这意味着,允许您的 UI 测试使用 iCloud 的设置要复杂得多,并且必须手动完成。

    首先,需要一个授权文件来指定应用想要使用的功能。我手动创建了以下文件(实际上是我复制了主目标的权利文件并编辑了它):

    <?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>aps-environment</key>
        <string>development</string>
        <key>com.apple.developer.icloud-container-identifiers</key>
        <array>
            <string>iCloud.com.yourid.EntitlementUITest</string>
        </array>
        <key>com.apple.developer.icloud-services</key>
        <array>
            <string>CloudKit</string>
        </array>
    </dict>
    </plist>  
    

    我将此文件添加到项目中。

    为了让 UI 测试目标能够使用 iCloud,现在需要在开发中心进行一些操作。

    在您的网络浏览器中,打开开发中心,然后在此处打开“证书、标识符和配置文件”。

    测试目标被视为新应用。因此,它需要一个单独的应用 ID。
    打开 App ID,并添加一个新 ID“EntitlementUITestUITests”。
    它应该是一个“Explicit App ID”,它使用你的测试目标的 bundle ID,这里是

    com.yourid.EntitlementUITest.  
    

    启用 iCloud 和推送通知。
    我不确定是否需要推送通知,但 Apple 告诉我这样做。可能,您可以在权利文件和此处省略它。 如果存在,请确保为推送通知服务指定了有效证书。
    启用 iCloud 时,请确保 iCloud.com.yourid.EntitlementUITest 是分配的 iCloud 容器中唯一选择的一个。

    接下来创建一个新的开发配置文件(使用您的 iOS 开发人员证书的文件)并与 com.yourid.EntitlementUITestUITests 关联。
    下载配置文件。

    返回 Xcode,使用标签 General 再次选择目标“EntitlementUITestUITests”。
    在签名部分中,取消选中自动管理签名,因为这不起作用。
    在 Signing (Debug) 中,在下拉菜单中选择 Provisioning profile 以导入您刚刚下载的配置文件。这也将在签名(发布)部分中选择。

    现在项目应该为测试而构建,没有错误。

    运行测试示例。它现在应该运行而没有运行时错误。

    结论:
    可以在 UI 测试中访问 CKContainer,但这非常复杂。
    为什么这个过程不像主要目标那样容易?
    也许开发者 UI 测试他们的 iCloud 应用程序的太少了,否则会编写更多对 Xcode 的增强请求……

    还有一件事:如果一切都做对了,测试只能在设备上运行,而不是在模拟器上。苹果表示,在模拟器上运行此测试会产生不可预测的结果。对我来说,这是可以预见的——它总是失败。

    【讨论】:

      猜你喜欢
      • 2015-04-17
      • 2016-07-09
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      • 1970-01-01
      • 2016-08-10
      相关资源
      最近更新 更多