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

拈花ヽ惹草 提交于 2019-11-26 17:01:01

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.

LorenzoValentijn

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 = 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'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")
}

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

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:



Then you need to create new scheme that will run project in "beta" configuration. To create scheme go here:



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



Then you need to add a key Config with value $(CONFIGURATION) the projects info property list like this:



Then its just the matter what you need in code to do something specific to beta build:

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
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!