Search code examples
iosswiftplist

Best practices for managing urls, settings, keys for plists in iOS for different build distributions?


What are best practices for keeping yourself sane with all the different settings for different environments and and generating different builds for them? As an example, our app connects to auth0 for login, and we have two different environments: stage + production for our backend service. Therefore, we have created two separate apps for auth0 (one for stage, other for production). What's a best practice for managing the settings for this on iOS? Do you create separate plist files for stage + prod with the various settings?

We generate two different builds of the app: one for stage (used in betas), and the other is a prod build to be put on the app store.


Solution

  • in Swift3 I have taken to using an enum to describe the different behaviour of my different targets.

    Step 1 - In the plist for the target I specify the target type, Alpha, Beta or Production.

    Indicate the type of build in the target plist

    Step 2 - I declare an enum to describe all the potential types of build

    enum RedactedAppVersion {
    
      case Alpha
      case Beta
      case Production
    
    }
    

    Step 3 - I implement a lazy global property to read the plist.

    lazy var appVersion: RedactedAppVersion = {
        if let temp = Bundle.main.object(forInfoDictionaryKey: "RedactedAppVersion") as? String {
    
          if temp.lowercased() == "alpha" {
            return RedactedAppVersion.Alpha
          }
    
          if temp.lowercased() == "beta" {
            return RedactedAppVersion.Beta
          }
        }
    
        return RedactedAppVersion.Production
      }()
    

    Step 4 - When I need to say get a path for an api, I interrogate the enum...

    4a - Add the following to the enum

    func apiPath() -> String {
        switch self {
        case .Alpha: return "https://test.redacted.com/v1/"
        case .Beta: return "https://test.redacted.com/v1/"
        case .Production: return "https://api.redacted.com/v1/"
    
        }
      }
    

    4b - I get the right path like this -

    let path = ApplicationManagerSingleton.sharedInstance.appVersion.apiPath() + "auth/sign-up"