Custom iOS Settings per Configuration
Sooner or later, many companies face a need to provide extra information or customisation for an app. For me it was usually the ability to target non-production servers and choose between dev, test and prod server environments.
There are multiple ways to achieve it, and the easiest is probably providing custom Settings bundle in iOS system Settings section for your app.
Adding a Settings Bundle
Adding a settings bundle is as simple as adding a new class.
In the example project I’ve added two bundles, ProdSettings
and DevSettings
.
After you’ve added them, remove the bundles from the Copy Bundle Resources
building phase, as you’ll be copying them manually in the next step.
Overriding the Bundle Based on the Configuration
In the build phases for your target, add a new build step New Run Script Phase
and place it after Copy Bundle Resources
one.
The script to copy the correct bundle would look something like this:
SRC_DIR="${PROJECT_DIR}/CustomSettingsBundle"
if [ "${CONFIGURATION}" != "Release" ]; then
cp -rf "${SRC_DIR}/DevSettings.bundle" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Settings.bundle"
else
cp -rf "${SRC_DIR}/ProdSettings.bundle" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Settings.bundle"
fi
Usage
Just like with normal settings, accessing values happens through UserDefaults
.
UserDefaults.standard.bool(forKey: "dev_preference_enabled")
Note that removing a setting from the bundle won’t clear the corresponding key in UserDefaults
, and until the setting is updated at least once, it will be nil
regardless of the default value in the plist
of the settings bundle.
Gotchas
Settings in the end product folder have to be named Settings.bundle
. Maybe you could change this requirement somewhere, but because of that example script also renames the folder itself.
iOS Settings are cached, so switching between configurations require project cleaning and may require an app reinstall to force the change of the settings contents. My suggestion would be to have beta/dev builds with separate bundle ID so you can have multiple versions of the app installed simultaneously without having to reinstall to test configurations.
Another issue is with the iOS Settings app itself. Sometimes all the apps would disappear from it, so a restart of the Settings app is often required if you switch and especially if you install an app while having Settings app open.
Alternatives?
Providing custom Settings bundle is very easy, but not very flexible. The next best thing is doing it via a special screen hidden under Debug/Beta-only button on the app’s landing screen.
The biggest gain is not having to leave the app to switch environment and not having to remember to kill the app if your settings are only read at launch-time. With a custom code you can make “Save” to perform data saving and then exit(0)
.
Top comments (0)