Settings.bundle
swift iOS settings tutorial Estimated reading time: 4 minutesMaking an app always requires a lot of debugging and testing. Sometimes additional information must be provided to the u’r QA team. But often this info is not needed on prod build.
To handle this situation we have a lot of options:
- implement a separate screen
- add hidden features (like a shake or 4-time tap on some place)
- add special frameworks that can handle and provide this info for u
- user remote config (like firebase or something similar)
- etc.
All solutions are great, but sometimes require a way to more effort to add them into the app.
Settings.bundle
An alternative to all this stuff may be a simple yet powerful solution: Settings.bundle
- a special kind of bundle provided by Apple to allow developers to add their app preferences into the iOS Settings app.
U can use this bundle for release and/or for debugging config.
The configuration for this feature is a simple one:
Create
Create a Settings.bundle
. Select create a new file and choose Settings.bundle
item:
The system then will check if u’r app bundle contains the
Settings.bundle
and if so - it will be included in the standardSettings.app
Configure
Configure content. U may have a nested page, localized resources, and even images inside u’r app settings. This content will be appended to u’r app default settings:
We can have a different options in there:
- textField (
PSTextFieldSpecifier
) - switch (
PSToggleSwitchSpecifier
) - slider (
PSSliderSpecifier
) - multivalue selection (
PSMultiValueSpecifier
) - title (
PSTitleValueSpecifier
) - group (
PSGroupSpecifier
) - child pane (
PSChildPaneSpecifier
)
I won’t describe the whole process of configuring the
Settings.bundle
content, thus this is perfectly described in Apple doc.
Example of the configuration
Control
Control the info/change
To control the data shown in settings and entered by a user we must note a few things:
1) Settings.bundle
all values are stored in a separate bundle inside a bundle of our app.
2) Stored format - XML key and values, so just a dictionary representation.
To manage all these settings we can use UserDefaults
, thus system automatically syncs data for us.
Note that you shouldn’t read from the settings bundle directly, as it makes no sense. You should always fetch and set user defaults using
NSUserDefaults
. When the user makes a change in the settings application, NSUserDefaults will reflect this automatically. They will always be kept in sync. source
To observe the changes in UserDefaults
we can use observers:
or with Combine
Note: To read the changes for the very first time we may get nothing due to early read requests and non-synced data. The workaround for this - is to read the data from
Settings.bundle
and register it inUserDefaults
using register(defaults:) method.
Manage
Manage environments
Now the interesting part - to allow Settings.bundle
only in some environments there is no build-in solution for that. But, as we know, this bundle is just a file inside the app bundle, so we can control the presence of this bundle, replace it and do whatever we want.
To do so, we may use a build script that can remove Settings.bundle
from the app bundle for Release config:
Pitfalls
Know u’r pitfalls
- The name of this bundle must be
Settings.bundle
. Other options will not work. - Different app targets can use different
Settings.bundle
(from different folders) - change only Target Memebership - on early access use register(defaults:) to register
Settings.bundle
onUserDefault
- only 1
Settings.bundle
can be in app bundle - use *.lproj folder with
<PLIST-NAME>.string
for localization - u may observe specific value in
UserDefault
using keyPath observer
Conclusion
Always look for a native solution, that for the majority part always easy to use and simpler to implement. Settings.bundle
is one of this stuff.
Resources
Share on: