是否可以在运行时检测通过TestFlight Beta(通过iTunes Connect提交)还是通过App Store安装了应用程序?您可以提交一个应用程序捆绑包,并同时通过两个应用程序捆绑包使用。是否有可以检测安装方式的API?还是收据中包含可以确定这一点的信息?
是否可以在运行时检测通过TestFlight Beta(通过iTunes Connect提交)还是通过App Store安装了应用程序?您可以提交一个应用程序捆绑包,并同时通过两个应用程序捆绑包使用。是否有可以检测安装方式的API?还是收据中包含可以确定这一点的信息?
Answers:
对于通过TestFlight Beta安装的应用程序,收据文件名为StoreKit\sandboxReceipt
vs.通常StoreKit\receipt
。使用,[NSBundle appStoreReceiptURL]
您可以在URL的末尾查找sandboxReceipt。
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSString *receiptURLString = [receiptURL path];
BOOL isRunningTestFlightBeta = ([receiptURLString rangeOfString:@"sandboxReceipt"].location != NSNotFound);
请注意,sandboxReceipt
当在本地运行内部版本以及在模拟器中运行内部版本时,这也是收据文件的名称。
StoreKit/sandboxReceipt
通过设备或模拟器上的Xcode作为调试版本安装时,我的iOS 8测试结果。因此,这可能无法准确区分testflight版本和所有其他版本。
根据组合答案,我创建了以下SWIFT帮助器类。使用此类,您可以确定它是调试,testflight还是appstore构建。
enum AppConfiguration {
case Debug
case TestFlight
case AppStore
}
struct Config {
// This is private because the use of 'appConfiguration' is preferred.
private static let isTestFlight = Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt"
// This can be used to add debug statements.
static var isDebug: Bool {
#if DEBUG
return true
#else
return false
#endif
}
static var appConfiguration: AppConfiguration {
if isDebug {
return .Debug
} else if isTestFlight {
return .TestFlight
} else {
return .AppStore
}
}
}
我们在项目中使用以下方法为每个环境提供不同的跟踪ID或连接字符串:
func getURL(path: String) -> String {
switch (Config.appConfiguration) {
case .Debug:
return host + "://" + debugBaseUrl + path
default:
return host + "://" + baseUrl + path
}
}
要么:
static var trackingKey: String {
switch (Config.appConfiguration) {
case .Debug:
return debugKey
case .TestFlight:
return testflightKey
default:
return appstoreKey
}
}
2016年5月2日更新: 使用#if DEBUG之类的预处理程序宏的前提是设置一些Swift编译器自定义标志。此答案中的更多信息:https : //stackoverflow.com/a/24112024/639227
#if targetEnvironment(simulator)
您可以使用它来确定您是否正在模拟器中运行。所以我有Simulator / TestFlight / AppStore选项(在我的情况下,它比首选Debug
):-)
现代Swift版本,说明了模拟器(基于公认的答案):
private func isSimulatorOrTestFlight() -> Bool {
guard let path = Bundle.main.appStoreReceiptURL?.path else {
return false
}
return path.contains("CoreSimulator") || path.contains("sandboxReceipt")
}
isTestFlight()
这不再起作用。使用其他方法。
这也适用:
if NSBundle.mainBundle().pathForResource("embedded", ofType: "mobileprovision") != nil {
// TestFlight
} else {
// App Store (and Apple reviewers too)
}
我Bundle+isProduction
在Swift 5.2上使用扩展名:
import Foundation
extension Bundle {
var isProduction: Bool {
#if DEBUG
return false
#else
guard let path = self.appStoreReceiptURL?.path else {
return true
}
return !path.contains("sandboxReceipt")
#endif
}
}
然后:
if Bundle.main.isProduction {
// do something
}
我将其用于项目的一种方式。步骤如下。
在Xcode中,转到项目设置(项目,而不是目标),然后将“ beta”配置添加到列表中:
然后,您需要创建将在“ beta”配置中运行项目的新方案。要创建方案,请转到此处:
可以根据需要命名此方案。您应该编辑此方案的设置。为此,请点击此处:
选择存档选项卡,您可以在其中选择 Build configuration
然后,您需要添加一个Config
值为$(CONFIGURATION)
项目信息属性列表的键,如下所示:
然后,这就是您需要在代码中执行特定于Beta构建的事情的问题:
let config = Bundle.main.object(forInfoDictionaryKey: "Config") as! String
if config == "Debug" {
// app running in debug configuration
}
else if config == "Release" {
// app running in release configuration
}
else if config == "Beta" {
// app running in beta configuration
}