Adding settings to your iOS app
--
Source: Apple docs.
I will tell you the reason why I am creating this article. Normally all my apps used to have login and logout option. So , to reset the app data I just had to click on logout button and it will call a routine function which will clear all the database data and userdefaults data. But, in one of the apps that I have made recently, I wanted to reset the app data once in a while. But the saddest part is that it didn’t had a login/logout option. Also, I didn’t want to add any button from inside the app to clear the data. This app had facebook and google subscription button in two different places inside the app which will go away once the subscription is successful. So, the testers had to reinstall the app four times to check this feature every time. I wanted to add a reset button so that testers can test this feature without uninstalling the app.
I also wanted to add the version and build number in the settings.
In iOS, the Foundation framework provides the low-level mechanism for storing the preference data. Apps then have two options for presenting preferences:
- Display preferences inside the app.
- Use a Settings bundle to manage preferences from the Settings app.
This what apple says in the official docs.
So an app can either show the settings inside the app or in the phone settings. Which option you choose depends on how you expect users to interact with preferences. The Settings bundle is generally the preferred mechanism for displaying preferences. However, games and other apps that contain configuration options or other frequently accessed preferences might want to present them inside the app instead. Regardless of how you present them, you use the NSUserDefaults
class to access preference values from your code.
The following table lists the type of controls that you can use in settings.bundle :
Every app with a Settings bundle has at least one page of preferences, referred to as the main page. If your app has only a few preferences, the main page may be the only one you need. If the number of preferences gets too large to fit on the main page, however, you can create child pages that link off the main page or other child pages. There is no specific limit to the number of child pages you can create, but you should strive to keep your preferences as simple and easy to navigate as possible.
A Settings bundle has the name Settings.bundle
and resides in the top-level directory of your app’s bundle. This bundle contains one or more Settings page files that describe the individual pages of preferences. It may also include other support files needed to display your preferences, such as images or localized strings.
You can localize the Info.plist file and show the settings in your desired language.Please read more in the official docs.
Adding the Settings Bundle
To add a Settings bundle to your Xcode project:
- Choose File > New > New File.
- Under iOS, choose Resource, and then select the Settings Bundle template.
- Name the file
Settings.bundle
.
In addition to adding a new Settings bundle to your project, Xcode automatically adds that bundle to the Copy Bundle Resources build phase of your app target. Thus, all you have to do is modify the property list files of your Settings bundle and add any needed resources.
The new Settings bundle has the following structure:
Click on the Root.plist file. You’ll see a property list like this:
The preference items is an array of dictionaries of controls . Go to Fig 1 to know what all controls we can add in our settings app bundle.
For this demo app, I only need one group, one title for showing the app version number , one title for showing the build number and one toggle switch for resetting the app. So delete all the items in the preference items array and add the above mentioned items.
So, for our app, Root.plist file should look like this:
The identifier is the Userdefaults key that you can use inside the code to do the appropriate changes. Don’t forget to add the default values for Title. It will not appear in the settings otherwise.
Tip: If you are concerned about the order of the controls in the plist, Right click on the
plist
file and open as source code. It is easy to edit the xml instead of the plist directly.
The settings control Ui will look like this for the above plist :
If your app is not showing these controls in settings page, then try deleting the derived data and reinstall the app. I had to reinstall so many times.It will work. Be patient. If you use simulator, the chances that the app doesn’t show the settings is more. It seems the simulator is still running your last iteration of your app. When you hit stop in Xcode it doesn’t stop the settings app. Click Command-Shift-HH to double-click the home button. Swipe up on the Settings app to kill the process. Start the Settings again, and settings refreshes itself.
Now, create a swift class called SettingsBundleHelper.swift to handle the settings changes etc.
I have added the code to reset data and set version number in appdelegate as follows:
func applicationDidBecomeActive(_ application: UIApplication) {SettingsBundleHelper.checkAndExecuteSettings()SettingsBundleHelper.setVersionAndBuildNumber()}
checkAndExecuteSettings()
resets data if “RESET_APP_KEY” key in UserDefaults is true. This will revert back the value of UserDefaults to false so that the switch in settings will toggle back to off state.
setVersionAndBuildNumber()
sets the version and build data. For this to work, the app should run at least once after installing. Otherwise it will select the default value provided.
Updating Defaults with Observers
The above method has a drawback that we have to call the code every time when the app launches. Alternatively you can set an observer for UserDefaults using NSUserDefaultsDidChangeNotification which is now UserDefaults.didChangeNotification.
But if you are using a lot of UserDefaults , then you should add proper condition checks and do the above code. Also in iOS versions prior to iOS 9, there can be a memory issue when you keep on receiving lot of notification like this. Prior to iOS9, we need to remove the observer for good memory management.
deinit { //Not needed for iOS9 and above. ARC deals with the observer in higher versions.NotificationCenter.default.removeObserver(self)}
Note: This is a basic tutorial on settings.bundle. There are a few more advanced options such as child settings pages , adding slider etc which are easy to implement which I haven’t mentioned here.
Note : If settings is not showing up for you, try using the App Switch UI (double-press Home button) to kill the Settings App and relaunch the app.
Full Project Github link(code is in swift 3).
Thanks for reading this. Enjoy!!