How to tell at runtime whether an iOS app is running through a TestFlight Beta install How to tell at runtime whether an iOS app is running through a TestFlight Beta install ios ios

How to tell at runtime whether an iOS app is running through a TestFlight Beta install


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.

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.


Based on combinatorial's answer I created the following SWIFT helper class. With this class you can determine if it's a debug, testflight or appstore build.

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    }  }}

We use these methods in our project to supply different tracking id's or connection string per environment:

  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


Modern Swift version, which accounts for Simulators (based on accepted answer):

private func isSimulatorOrTestFlight() -> Bool {    guard let path = Bundle.main.appStoreReceiptURL?.path else {        return false    }    return path.contains("CoreSimulator") || path.contains("sandboxReceipt")}