Configuration and User-Defined setting in iOS
I ran into a challenge: support different countries with different app’s name, icon but same code. “Green” app is the original app, there is a need to convert the original “Green” app to another app with different properties, which in the demo is known as the “Red” app.
Cloning to different projects is not my solution. Did some research and finally, I did this solution. Use different Build Settings and Schemes for markets. This is how I did.
Add configurations
- Access to Project Setting/Info. Rename configuration Debug and Release to Debug_Red and Release_Red
- Duplicate these 2 configurations and change name to Debug_Green and Release_Green
Add Schemes
- Select current scheme and Edit Scheme…
-
Select Duplicate Scheme, Manage Schemes…
-
Select a scheme and press Return key to rename.
-
Double click to Scheme Red and check left hand side setting
-
Make sure Debug, Test, Analyze is Debug_Red configuration and Profile, Release is Release_Red. To change configuration, select Info and change in Build Configuration.
- Same to Scheme Green
Add User-Defined Setting
Red and Green have different names, bundle IDs, versions, build numbers. I have to add some User-Defined Setting
- Select Project setting/Editor/Add Build Setting/Add User-Defined
-
Add some settings:
app_name
,bundle_id
,version
,build_number
-
Add value to new settings
Bind User-Defined Setting
- In Tab
Build Setting
, searchProduct Bundle Identifier
and enter value$(bundle_id)
- Select Tab
General
- Enter
$(app_name)
toDisplay Name
,$(version)
toVersion
,$(build_number)
toBuild
Result
-
Add some UILabel to Storyboard Main and connect outlets
-
Add some code to show setting of the running app.
appNameLabel.text = Bundle.main.object(forInfoDictionaryKey: “CFBundleDisplayName”) as? String
versionLabel.text = Bundle.main.infoDictionary?[“CFBundleShortVersionString”] as? String
buildLabel.text = Bundle.main.infoDictionary?[“CFBundleVersion”] as? String
bundleIdLabel.text = Bundle.main.bundleIdentifier
- See how it works
Other setting
-
We can apply this solution to Launchscreen, App Icon by adding 2 Launchscreens, 2 App Icons with same name, just different suffix.
-
We can set Launchscreen same to Display Name but App Icon needs to be configured same to Product Bundle Identifier
Besides that, we need to change font family, theme color, text color depend on App. Here how to do.
Configure in code
protocol Configuration {
var themeColor: UIColor { get set }
var textColor: UIColor { get set }
}
struct RedConfiguration: Configuration {
var themeColor = UIColor.red
var textColor = UIColor.white
}
struct GreenConfiguration: Configuration {
var themeColor: UIColor = UIColor.green
var textColor = UIColor.blue
}
- In my main setting class
let config: Configuration = {
if let app = Bundle.main.object(forInfoDictionaryKey: “CFBundleDisplayName”) as? String {
if app == “Red” {
return RedConfiguration()
}
else {
return GreenConfiguration()
}
}
return RedConfiguration()
}()
Final
My demo source is available on Github.