我想在调试屏幕中检查这个以获取构建信息。有没有办法在运行时检查这个?
我意识到我可以为构建或类似设置编译器标志,但如果有一个我可以利用的现有方法,我想利用它。
我想在调试屏幕中检查这个以获取构建信息。有没有办法在运行时检查这个?
我意识到我可以为构建或类似设置编译器标志,但如果有一个我可以利用的现有方法,我想利用它。
虽然我同意 Abhi Beckert 的观点,即运行时是执行此操作的错误时间(使用预处理器指令和构建设置!),但我想澄清先前答案/评论中的一些细节和推测,并对您的事情有所了解可以做。请耐心等待,这将是一个更长的答案......
有很多数据可以放在“构建信息”的通用保护伞下。此类内容的非详尽列表包括:构建配置、代码签名身份、构建时间、构建日期、营销版本号、SCM 修订号、SCM 分支名称、供应配置文件团队身份、供应配置文件到期、CI 内部版本号.. .这个名单还在继续。
假设目前您的问题只集中在获取有关 iOS 证书类型和用于构建的配置文件的信息,那么我将不得不用一个非常坚定的“否”作为问题的答案:是否有在运行时检查 [使用现有 API 方法构建信息] 的方法? 顺便说一句:这两个数据点在 Xcode 4.6.x 构建设置中统称为“代码签名身份”,或者为您的命令行构建设置爱好者称为“CODE_SIGN_IDENTITY”。
在提出这个问题时,没有单一的公共 iOS API 可供您调用以获取有关当前正在运行的应用程序的代码签名类型的信息。这背后的可能原因很多,但这里有几个例子:
然后,这个假设的一站式 API 需要在运行时访问您的所有构建配置数据、证书和配置文件,以便能够解开在编译时应用的“有效”设置,并将所有这些数据减少到有限字符串...仅用于开发人员诊断视图...不是任何想象都无法实现的壮举,但是对于开发人员利益微不足道的这种潜在的计算密集型操作肯定会在几乎任何人的优先级列表中排名较低。考虑到其他选项(如编译时标志!)更可靠,设置成本更低,并且从长远来看更易于维护,它将被踢得更远。
现在,关于“我可以在运行时做吗?”这个半潜伏的问题。我会强调说“是的,你可以。”
如您所知,设备构建是唯一需要代码签名的构建类型。该过程的一部分在名为“embedded.mobileprovision”的主包中创建一个文件。这是您的应用程序沙箱拥有的文件,因此您绝对有能力以编程方式打开:
[[NSBundle mainBundle] pathForResource:@"embedded.mobileprovision" ofType:nil]
.mobileprovision 文件采用 PCKS#7 编码,包含二进制和文本数据。您寻找的信息是嵌入在 PCKS#7 数据中的基于文本的 plist 的信息。首先,使用 OS X,让我们从您的一个设备构建中查看以下文本数据:
您会立即注意到有很多二进制数据,但您可以辨认出部分文本数据。向右滚动,您将看到 plist 样式的 xml,只是在此视图中阅读起来并不容易。我们可以使用 OS X 命令行工具以更有条理的方式查看这些数据:
这会将 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 的评论。对于不到 1% 的用例来说,这是一项相当大的工作量,而且还有更简单的解决方案!此外,开发者诊断视图不应该出现在 App Store 发布版本中,但是包含无关代码的决定完全掌握在您手中。
我希望这可以解决任何挥之不去的问题,但如果没有,请发表评论,我们可以看看我们能做些什么。
这可能是您正在寻找的。Abhi 有一个很好的、彻底的解释,这个要点有实际的代码:
运行时是执行此操作的错误时间。
如果您尝试这样做,您的应用可能会被商店拒绝。或者它可能被批准,然后你做一个紧急的错误修复发布,那个可能会被拒绝。
正如@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
}