【问题标题】:Check if app is ad-hoc|dev|app-store build at run time在运行时检查应用程序是否是 ad-hoc|dev|app-store 构建
【发布时间】:2013-07-09 04:43:00
【问题描述】:

我想在调试屏幕中检查这个以获取构建信息。有没有办法在运行时检查这个?

我意识到我可以为构建或类似设置设置编译器标志,但如果有我可以利用的现有方法,我想利用它。

【问题讨论】:

  • 这个 ios-dev... 链接是 404 未找到

标签: ios ad-hoc-distribution


【解决方案1】:

虽然我同意 Abhi Beckert 的观点,即运行时是执行此操作的错误时间(使用预处理器指令和构建设置!),但我想澄清上一个答案/cmets 中的一些细节和推测并发出一些光关于你可以做的事情。请耐心等待,这将是一个更长的答案......

有很多数据可以归于“构建信息”的通用保护伞下。此类内容的非详尽列表包括:构建配置、代码签名身份、构建时间、构建日期、营销版本号、SCM 修订号、SCM 分支名称、供应配置文件团队身份、供应配置文件到期、CI 内部版本号.. .这个名单还在继续。

假设您的问题暂时集中在获取有关用于构建的 iOS 证书类型和配置文件的信息,那么我将不得不以非常坚定的“否”作为问题的答案: 有没有办法在运行时检查 [使用现有 API 方法构建信息]? 顺便说一句:这两个数据点在 Xcode 4.6.x 构建设置中统称为“Code Signing Identity”或“CODE_SIGN_IDENTITY”为您的命令行构建设置爱好者。

截至提出此问题时,没有单一的公共 iOS API 可供您调用以获取有关当前运行应用程序的代码签名类型的信息。这背后的可能原因有很多,但这里有几个例子:

  1. 允许开发人员构建自己的构建方案和构建配置。这意味着我们可以有一个方案和一个构建配置,或者一个方案和几十个构建配置,甚至是数千个。自然地,可以为每个方案分配不同的构建配置,并且可以为每个配置分配不同的代码签名身份。正如您可能猜到的那样,开发人员或团队不需要太多的自定义,很快就会变得混乱。
  2. 代码签名身份仅要求为当前应用标识符颁发的未过期的配置文件包含用于签署二进制文件的证书的公钥副本。对于那些在团队中工作的人,您可能有一个包含团队中开发人员的所有证书的单一配置文件,或者您可以为团队中的每个开发人员制作单独的配置文件,其中只包含他们的证书。这是开发者选择构建应用的方式的另一个变化点。
  3. 开发人员可以共享一个证书 (tsk tsk) 或获得自己的证书...是的,您猜对了,还有更多变化。

然后,这个假设的一站式 API 需要在运行时访问您的所有构建配置数据、证书和配置文件,以便能够解开在编译时应用的“有效”设置并减少所有这些数据缩小到一个有限的字符串...仅用于开发人员诊断视图...这不是任何想象都无法实现的壮举,但是这种潜在的计算密集型操作对于可忽略的开发人员利益肯定会在几乎任何人的优先级列表中排名较低。考虑到其他选项(如编译时标志!)更可靠、设置成本更低且从长远来看更易于维护,它会被进一步排在优先级列表的下方。

现在,关于“我可以在运行时执行此操作吗?”这个半潜伏的问题。我会强调说“是的,你可以。”

如您所知,设备构建是唯一需要代码签名的构建类型。该过程的一部分在名为“embedded.mobileprovision”的主包中创建一个文件。这是您应用的沙盒所拥有的文件,因此您绝对可以通过编程方式打开:

[[NSBundle mainBundle] pathForResource:@"embedded.mobileprovision" ofType:nil]

.mobileprovision 文件采用 PCKS#7 编码,包含二进制和文本数据。您寻找的信息是嵌入在 PCKS#7 数据中的基于文本的 plist 的信息。首先,使用 OS X,让我们从您的一个设备版本中查看以下文本数据:

  1. 右键单击您的构建设备 .app 包并选择“显示包内容”
  2. 将 embedded.mobileprovision 文件复制到易于访问的位置。
  3. 使用您喜欢的文本编辑器打开该文件。

您会立即注意到有很多二进制数据,但您可以辨认出部分文本数据。向右滚动,您将看到 plist 样式的 xml,只是在此视图中阅读起来并不容易。我们可以使用 OS X 命令行工具以更有条理的方式查看这些数据:

  1. 打开终端并“cd”到包含您的 embedded.mobileprovision 副本的文件夹。
  2. 运行:security cms -D -i embedded.mobileprovision

这将在终端窗口中显示 plist xml 以供您阅读,并以一个很好的选项卡格式显示。如果您对 Ad-Hoc 构建、Dev 构建和 App Store 构建重复此过程,您将开始注意到本文中指示相应构建类型的键。对于使用“iPhone Developer: ...”证书签名的构建(或您在原始帖子中列出的“Dev”构建),请查找:

<key>get-task-allow</key>
<true/>

“get-task-allow”键用于指示 iOS 应用是否允许调试器附加到它。对于“iPhone 开发人员”签名的二进制文件,这是有道理的 - 在将代码从 Xcode 推送到您的设备以进行测试时,您通常需要能够在设备上进行调试。

“Ad-Hoc”和“App Store”之间的区别需要一些额外的检查。对于这两种分布,相同的“get-task-allow”键将设置为 false:

<key>get-task-allow</key>
<false/>

但是,“Ad-Hoc”构建具有一组已定义的“ProvisionedDevices”,而“App Store”构建中不存在:

<key>ProvisionedDevices</key>
<array>
    <string>abcdef01234567890abcdef01234567890abacde</string>
    <string>1abcdef01234567890abcdef01234567890abacd</string>
    <string>2abcdef01234567890abcdef01234567890abacd</string>
</array>

那么这对于运行时检查问题实际上意味着什么?是的,你可以做到这一点,方法是从主包中打开 embedded.mobileprovision 文件,并从中解析数据以做出明智的决定,但这是你自己完全负责实现的事情。您需要添加逻辑来处理该文件丢失的情况(例如模拟器构建)并解析 PCKS#7 数据或可靠地提取文件的 ASCII 内容,您的代码可以在该文件上运行一系列字符串搜索.很可能很明显,这将需要不平凡的努力来获得一个有点脆弱的解决方案,否则这些解决方案可以很容易地通过构建设置和预处理器宏来适应,正如 Abhi Beckert 在上一个答案中概述的那样。

App Store 被拒绝的风险如何?这是“非法”还是“颠覆”?

假设您在读取和解析 Embedded.mobileprovision 文件的内容时使用所有公共 API,这在 App Store 的当前条款中是完全允许的。您应用程序沙箱中的任何内容都是公平的游戏,包括 Embedded.mobileprovision(如果它恰好存在)。我仍然强烈警告不要走这条路,与 Abhi Beckert 的 cmets 相呼应。对于不到 1% 的用例来说,这是一项相当大的工作量,而且还有更简单的解决方案!此外,开发者诊断视图不应出现在 App Store 发布版本中,但是否包含无关代码的决定完全掌握在您手中。

我希望这可以解决任何挥之不去的问题,但如果没有,请在评论中折腾,我们可以看看我们能做些什么。

【讨论】:

  • 非常感谢您的详细回答。我学到了一些东西。出于明显的原因,我计划坚持使用编译时参数。我从来没有打算做那么多工作,而是希望我忽略了一个简单的 API。
  • 这里需要注意的重要一点是来自应用商店的构建没有embedded.mobileprovision 文件。该文件似乎在 App Store 上发布之前已被删除。甚至 TestFlight 构建也会删除此文件。
  • 是的,这是正确的;它被用作 App Store 审核验证过程的一部分,然后被删除。
【解决方案2】:

这可能是您正在寻找的。 Abhi 有一个很好、彻底的解释,这个要点有实际的代码:

https://github.com/blindsightcorp/BSMobileProvision

【讨论】:

    【解决方案3】:

    运行时是错误的时间。

    如果您尝试这样做,您的应用可能会被商店拒绝。或者它可能会被批准,然后你发布一个紧急的错误修复版本,而那个版本可能会被拒绝。

    正如@rmaddy 在评论中建议的那样,您应该在编译时进行。

    编辑您的项目设置以定义此常量:CONFIGURATION_$(CONFIGURATION),然后在您的代码中执行此操作:

    #if defined (CONFIGURATION_Debug) || defined (CONFIGURATION_Adhoc)
      NSLog( @"Warning message");
    #endif
    

    来源/更多详情:http://ios-dev.gravitini.com/2009/02/identifying-current-xcode-configuration.html

    如果你愿意,你可以在它周围包裹一个运行时函数。也许:

    void debugLog(NSString *str)
    {
        #if defined (CONFIGURATION_Debug)
          NSLog(@"%@", str);
        #endif
    }
    

    【讨论】:

    • 当你说它可能会被拒绝时,为什么?这是非法举动吗?
    • 我不知道是否允许,但这将是一个灰色地带,如果允许,六个月内可能不会。
    猜你喜欢
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 2013-02-13
    • 2011-01-26
    • 2014-01-02
    • 1970-01-01
    相关资源
    最近更新 更多