Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three slightly different Apps from one code base

Hy there I would like to have three apps depending, which are based on the same code:

  1. MyAppDevelopment (Builds from Xcode that are deployed to the device)

  2. MyAppPreview (Beta testing)

  3. MyApp (Release)

It should be possible to have all of the three Apps installed on a device and they'd have their own icon to nicely distinguish them visually.

Now I know that I could have three different targets with their respective Info.plist file, but I would rather use Xcode's configurations so that I don't have to maintain three different targets. Is this possible using configurations, the problem is that the App identifier is stored in the Info.plist file, which can be defined per-target...

like image 711
Besi Avatar asked Jan 21 '12 20:01

Besi


1 Answers

Using different targets for different editions of Apps provides more flexibility and lets you easily change the bundle identifier and the icon etc once you specify a different plist file per target. However, the configurations are more deeply integrated with Xcode and you can adjust any build setting per configuration.

After some more research I figured out how to get the best of both worlds with just one target:

  • Create the desired configurations in Xcode: ProjectName > ProjectName > Info. For example:
    • Debug
    • Preview
    • Release
  • Now these three configurations are available for all the build settings.
  • The three Apps should co-exist on a device. I want to be able to have all three versions of the App on one device, for this all three types need a different bundle identifier. The original Identifier could be com.company.${PRODUCT_NAME:rfc1034identifier}.

    • To achieve this go to MyProject > MyApp (Target) > Build settings and click on the button (+) Add Build Setting
    • Add the new key ${APP_ID} and set the values like this and note that the release configuration should not have a suffix:

      APP_ID > 'com.company.MyApp-debug'
             > 'com.company.MyApp-preview'
             > 'com.company.MyApp'
      
    • Now in your Info.plist change the Bundle Identifier value to ${APP_ID}
  • You can do the same with the Bundle Display Name or the Icon attribute so that you can easily distinguish the app at one glance.

  • You can set Preprocessor macros for your configurations in order to be able to detect the current configuration in your code. This is done by default for the debug configuration: DEBUG=1.

Advantages

  • Since the three Apps have their own identifier, you won't override the latest preview build when testing the current App in Xcode.
  • Nicely integrated into Xcode and offers a high flexibility
    All build settings can now individually be changed per configuration
  • New configurations can easily be added by cloning existing configurations within Xcode
  • No need for additional targets
    Targets are IMHO better for completely different artifacts like libraries or testing targets that have a different code base.
  • The configurations can be used in code if required.
  • Different Service URLS etc. can be used for different environments. See this great post (Thanks to Jonah!) that shows how to do this using a special plist file.
  • No use of any hacky scripts which are hard to maintain

Disadvantages

  • With using targets it would be possible to exclude some frameworks from a type of App. So for example you could exclude some analytics library from the debug edition of your App.

  • Update: You can't use substitutions like com.company.${PRODUCT_NAME:rfc1034identifier} for User defined Build Settings. So you'll have to write out the bundle whole bundle identifier in this case.

  • Update: Some settings which should be made "configuration aware" move to the User-Defined section of the Build Settings, which might feel unusual for some developers.

The result

Result http://i.minus.com/jbwPgEiBra39dL.png

like image 80
Besi Avatar answered Nov 15 '22 21:11

Besi