如何在运行时判断 iOS 应用程序是否通过 TestFlight Beta 安装运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26081543/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to tell at runtime whether an iOS app is running through a TestFlight Beta install
提问by combinatorial
Is it possible to detect at runtime that an application has been installed through TestFlight Beta (submitted through iTunes Connect) vs the App Store? You can submit a single app bundle and have it available through both. Is there an API that can detect which way it was installed? Or does the receipt contain information that allows this to be determined?
是否可以在运行时检测到应用程序已通过 TestFlight Beta(通过 iTunes Connect 提交)与 App Store 安装?您可以提交一个应用程序包,并通过两者都可以使用它。是否有可以检测安装方式的 API?或者收据是否包含可以确定这一点的信息?
采纳答案by combinatorial
For an application installed through TestFlight Beta the receipt file is named StoreKit\sandboxReceipt
vs the usual StoreKit\receipt
. Using [NSBundle appStoreReceiptURL]
you can look for sandboxReceipt at the end of the URL.
对于通过 TestFlight Beta 安装的应用程序,收据文件的名称StoreKit\sandboxReceipt
与通常的StoreKit\receipt
. 使用[NSBundle appStoreReceiptURL]
您可以在 URL 末尾查找 sandboxReceipt。
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSString *receiptURLString = [receiptURL path];
BOOL isRunningTestFlightBeta = ([receiptURLString rangeOfString:@"sandboxReceipt"].location != NSNotFound);
Note that sandboxReceipt
is also the name of the receipt file when running builds locally and for builds run in the simulator.
请注意,sandboxReceipt
在本地运行构建和在模拟器中运行的构建时,这也是接收文件的名称。
回答by LorenzoValentijn
Based on combinatorial's answerI created the following SWIFT helper class. With this class you can determine if it's a debug, testflight or appstore build.
根据组合的回答,我创建了以下 SWIFT 帮助程序类。通过此类,您可以确定它是调试、测试飞行还是应用商店构建。
enum AppConfiguration {
case Debug
case TestFlight
case AppStore
}
struct Config {
// This is private because the use of 'appConfiguration' is preferred.
private static let isTestFlight = NSBundle.mainBundle().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
}
}
}
We use these methods in our project to supply different tracking id'sor connection stringper environment:
我们在项目中使用这些方法为每个环境提供不同的跟踪 ID或连接字符串:
func getURL(path: String) -> String {
switch (Config.appConfiguration) {
case .Debug:
return host + "://" + debugBaseUrl + path
default:
return host + "://" + baseUrl + path
}
}
OR:
或者:
static var trackingKey: String {
switch (Config.appConfiguration) {
case .Debug:
return debugKey
case .TestFlight:
return testflightKey
default:
return appstoreKey
}
}
UPDATE 05-02-2016:A prerequisite to use a preprocessor macro like #if DEBUG is to set some Swift Compiler Custom Flags. More information in this answer: https://stackoverflow.com/a/24112024/639227
2016 年 5 月 2 日更新:使用像 #if DEBUG 这样的预处理器宏的先决条件是设置一些 Swift 编译器自定义标志。此答案中的更多信息:https: //stackoverflow.com/a/24112024/639227
回答by Serhii Yakovenko
Modern Swift version, which accounts for Simulators (based on accepted answer):
现代 Swift 版本,它考虑了模拟器(基于接受的答案):
private func isSimulatorOrTestFlight() -> Bool {
guard let path = Bundle.main.appStoreReceiptURL?.path else {
return false
}
return path.contains("CoreSimulator") || path.contains("sandboxReceipt")
}
回答by Marián ?erny
Update
更新
This does not work any more. Use other method.
这不再起作用了。使用其他方法。
Original answer
原答案
This also works:
这也有效:
if NSBundle.mainBundle().pathForResource("embedded", ofType: "mobileprovision") != nil {
// TestFlight
} else {
// App Store (and Apple reviewers too)
}
Found in Detect if iOS App is Downloaded from Apple's Testflight
在Detect if iOS App is Downloaded from Apple's Testflight 中找到
回答by Denis Kutlubaev
I use extension Bundle+isProduction
on Swift 5.2:
我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
}
}
Then:
然后:
if Bundle.main.isProduction {
// do something
}
回答by Klemen
There is one way that I use it for my projects. Here are the steps.
有一种方法可以将它用于我的项目。以下是步骤。
In Xcode, go to the the project settings (project, not target) and add "beta" configuration to the list:
在 Xcode 中,转到项目设置(项目,而不是目标)并将“beta”配置添加到列表中:
Then you need to create new scheme that will run project in "beta" configuration. To create scheme go here:
然后你需要创建新的方案,以“beta”配置运行项目。要创建方案去这里:
Name this scheme whatever you want. The you should edit settings for this scheme. To do this, tap here:
随意命名这个方案。您应该编辑此方案的设置。为此,请点击此处:
Select Archive tab where you can select Build configuration
选择存档选项卡,您可以在其中选择 Build configuration
Then you need to add a key Config
with value $(CONFIGURATION)
the projects info property list like this:
然后,你需要添加一个键Config
与值$(CONFIGURATION)
的项目信息属性列表如下:
Then its just the matter what you need in code to do something specific to beta build:
然后就是你需要在代码中做一些特定于 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
}