Hello! In this post, I’m going to show you guys how to use a remote config file for your iPhone/iPad application. In my experience, this isn’t something the client asks for or thinks about during requirements gathering (unless they have a technical manager on their side). However, even though it isn’t one of those things they ask for, it WILL come up later on after the app is in the App Store and they want to change a config variable!
So, the best thing to do is to be proactive about it and suggest adding it to the scope in the beginning of the project!
The basic idea is that we will keep a file on a server that we can control and have our iOS app fetch that file on the application start up. It will parse the file for all of the configuration variables it needs and use those values. This way you can change the variables remotely even after the app is in the App Store.
Tips For Your Remote Config File
1. Don’t store sensitive information in your config file unless the connection is secure or you’ve encrypted the info in the file. Personally, I’ll consider all the things that the client may want to change remotely after the app has been submitted (as well as ask them), and then ask them out of that list, if there is anything that is sensitive information. If there is, I’ll see if it can be omitted from the remote config.
2. Most of the time, dynamic urls and feeds, analytics suite ids or advertising campaign ids will be good to store in the remote configuration file. Those are some of the common things that may change in between app updates.
3. The app may not have an internet connection when it starts up so you’ll need to think about what happens if your iPhone app can’t fetch the config file. (Or what would happen if the server hosting your config file goes down?).
In the past, what I’ve done is ship the app with a default configuration file so if it can’t fetch the remote config on the first launch, it has fall back values. But after it has fetched the remote config, it will store those values in local storage until the next fetch. If it can’t fetch the remote config the next time the app starts, it will use the stored values. If it successfully fetches it, it will update the values in local storage and use the new values.
4. You’ll have to think about how to manage staleness of the config variables that the app is using. Meaning, the user could potentially have the app open for the whole day so if you change the config variables in the middle of the day and the iOS app only checks the config file once during start up, how do you “force” the user to re-fetch the config file to get your updated variables?
If your config file is small enough (and it should be tiny! You shouldn’t trying to stuff everything into this remote file), you may be able to get away with checking your remote config every time the app comes back into the foreground or starts up. You can use a timestamp variable in your config so the app can check it to see if it needs to update the local values.
5. What format should your file be in? JSON? XML? Comma-delimited? It can be in any sort of schema you want because you’re the one who is going to be writing the parsing logic in your iPhone/iPad application!
One thing to consider is that it may not be YOU who will be changing the values in the config file so you want to make it easy and fool-proof to update the config file. I’ve mostly used a plist XML schema in the past because it’s easy for the client to load it up in a plist viewer and edit the values with a UI.
The Remote Configuration Schema
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>FeedUrl</key> <string>http://google.com</string> <key>AnalyticsId</key> <string>93476032562</string> </dict> </plist>
There are a few PLIST viewer/editors out there but even if you open the PLIST file in a standard text editor, it’s very readable and easy to understand. The best part of doing it in the PLIST schema is how easy it is to parse into an NSDictionary in Objective-C.
Fetching The Remote Config File
Here’s an example of how you can fetch and parse the remote config file.
Lines 1-6 is setting up the NSURLRequest and NSURLConnection. Notice in line 3 that we specify that nothing should be cached. I wrote about it in this post.
In line 7, we fetch the file and in line 11, we check if there’s been an error getting a response.
In lines 14-19, we parse the NSData into a dictionary and in lines 25-26, we’re taking the config values from the dictionary and assigning it to vars.
NSURL *configUrl = [NSURL URLWithString:@"http://yourdomain.com/yourconfig.xml"]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:configUrl cachePolicy:NSURLCacheStorageNotAllowed timeoutInterval:20.0]; NSURLResponse *response = nil; NSError *error = nil; NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error]; // Check no error, then parse data if (error == nil) { // Parse response into a dictionary NSPropertyListFormat format; NSString *errorStr = nil; NSDictionary *dictionary = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&errorStr]; if (errorStr == nil) { @try { // Try to retrieve the config values from the xml NSString *feedUrl = [dictionary objectForKey:@"FeedUrl"]; NSString *analyticsId = [dictionary objectForKey:@"AnalyticsId"]; } @catch (NSException *e) { // Error with retrieving the key } } else { // Error with parsing data into dictionary } }
And that’s all there is to it! Hope that’s something that you guys can put to good use in your projects. Please leave a comment below and let me know what you think!