在运行时检查应用程序是否是特别的| dev | app-store构build

我想在debugging屏幕上查看这个版本信息。 有没有办法在运行时检查这个?

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

虽然我同意Abhi Beckert所说的运行时间是错误的时间(使用预处理器指令和构build设置!),但我想澄清一些前面的答案/注释中的一些细节和推测, 可以做。 忍受我,这将是一个更长的答案…

有一些数据可以在“构build信息”的通用保护下进行。 这些事情的非详尽列表将包括:构buildconfiguration,代码签名标识,生成时间,生成date,市场版本号,SCM修订号,SCM分支名称,供应configuration文件团队标识,供应configuration文件过期,CI内部版本号。这份名单继续下去。

假设目前你的问题只是关注获取有关用于构build的iOS证书和configuration文件types的信息,那么我将不得不采用非常坚定的“否”作为问题的答案: 是否存在在运行时检查[使用现有API方法构build信息]的方法? 简而言之,这两个数据点在Xcode 4.6.x Build Settings或“CODE_SIGN_IDENTITY”中称为“ 代码签名标识 ”,供命令行编译爱好者使用。

在问这个问题的时候,没有单独的公共iOS API,您可以调用它来获取有关当前正在运行的应用程序的代码签名types的信息。 这背后的可能原因很多,但这里有几个例子:

  1. 开发人员可以构build自己的构buildscheme并构buildconfiguration。 这意味着我们可以有一个scheme和一个构buildconfiguration,或者一个scheme和几十个构buildconfiguration,甚至每个构buildconfiguration数千个。 当然,每个scheme可以被分配不同的构buildconfiguration,并且这些configuration可以分别被分配不同的代码签名标识。 正如你可能猜到的那样,开发人员或团队不需要太多的定制就可以很快得到混乱。
  2. 代码签名身份只需要为当前应用程序标识符发出的未过期的提供configuration文件包含用于签署二进制文件的证书的公钥副本。 对于在团队中工作的人员,您可能只有一个configuration文件,其中包含团队中开发人员的所有证书,或者您可以为团队中仅包含其证书的每个开发人员制定单独的configuration文件。 这是开发人员如何select构build应用程序的又一点变化。
  3. 开发人员可以共享一个证书(tsk tsk)或者发布他们自己的证书…是的,你猜对了,甚至更多的变化。

这个假设的一站式API将需要在运行时访问所有的构buildconfiguration数据,证书和configuration文件,以便能够解开编译时应用的“有效”设置,并将所有数据减less到有限的string……只是对于开发人员的诊断视图…不是任何想象中的不可能的壮举,但是对于微不足道的开发人员的好处而言,这种潜在的计算密集型操作在任何人的优先级列表上肯定都排在低位。 如果其他选项(如编译时间标志!)更可靠,安装成本更低,并且从长远来看更容易维护,那么它将会被优先级列表踢得更高。

现在,关于“我可以在运行时做这个事情吗?”的半潜藏问题。 我会强调说'是的,你可以'。

如您所知,设备构build是唯一需要代码签名的构build。 部分进程在名为“embedded.mobileprovision”的主包中创build一个文件。 这是应用程序沙箱所拥有的文件,因此您绝对有能力以编程方式打开:

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

.mobileprovision文件是PCKS#7编码,包含二进制和文本数据。 您所寻求的信息是embedded在PCKS#7数据中的基于文本的plist。 首先,使用OS X让我们看看你的一个设备版本中的文本数据:

  1. 右键单击您的版本设备.app包并select“显示包内容”
  2. 将embedded.mobileprovision文件复制到一个容易访问的地方。
  3. 用你喜欢的文本编辑器打开该文件。

你马上注意到,有很多二进制数据,但你可以确定文本数据的一部分。 向右滚动,您将看到plist风格的xml,只是在这个视图中阅读起来并不那么容易。 我们可以使用OS X命令行工具以更有组织的方式查看这些数据:

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

这将显示plist xml到terminal窗口,以一个很好的标签格式进行浏览。 如果您为Ad-Hoc构build,开发构build和App Store构build重复此过程,则您将会注意到本文中用于指示各个构buildtypes的键。 对于使用“iPhone Developer:…”证书签名的版本(或“开发版”按照您在原文中列出的版本构build),请查找:

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

'get-task-allow'键是用来指示iOS的,如果应用程序允许debugging器连接到它的话。 如果是“iPhone开发者”签名的二进制文件,这是非常有意义的 – 当您将代码从Xcode推送到您的设备以进行testing时,您通常需要能够在设备上进行debugging。

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

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

然而,“Ad-Hoc”构build具有定义的“ProvisionedDevices”集合,不存在于“App Store”构build中:

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

那么对于运行时检查问题,这在实际中意味着什么呢? 是的,你可以做到这一点,通过从主包中打开embedded.mobileprovision文件并parsing数据来做出明智的决定,但这是你自己实现的全部责任。 您需要添加逻辑来处理缺less该文件的情况(例如,模拟器构build),并parsingPCKS#7数据或可靠地提取文件的ASCII内容,在该文件上您的代码可以运行一系列stringsearch。 可能很明显,这将需要不小的努力来解决一个稍微脆弱的解决scheme,否则可以很容易地通过构build设置和预处理器macros来解决上述答案中概述的Abhi Beckert。

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

假定在读取和parsingembedded.mobileprovision文件的内容时使用了所有的公共API,这是App Store的当前条款所完全允许的。 如果碰巧存在的话,那么在你的应用的沙箱中的任何东西都是公平的游戏,包括embedded.mobileprovision。 我仍强烈反对阿比·贝克特的评论。 对于less于1%的用例来说,这是一个相当大的努力,并且在那里有更容易的解决scheme! 此外,开发者诊断视图不应该在App Store发布版本中,但是包含无关代码的决定完全掌握在你的手中。

我希望这可以解决任何悬而未决的问题,但如果不是,请评论一下,我们可以看看我们能做些什么。

这可能是你在找什么。 阿比有一个很好的,彻底的解释,这个要点有实际的代码:

https://github.com/blindsightcorp/BSMobileProvision

运行时间是这样做的错误时间。

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

正如@rmaddy在评论中所build议的那样,你应该在编译时做。

编辑你的项目设置来定义这个常量: 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 }