Reputation: 7133
I'm currently in the process of adapting an existing iOS app into what will be a family of very similar apps (each app instance will probably map to a different country/region).
I'm planning on having a different build target for each of these instances, and the only differences between them should be:
The code itself should be the same on all apps.
What I'd like to know is what you consider to be best practices for managing a family of applications like this.
Regarding images and localizations (or resources in general), it should simply be a matter of adding/removing the appropriate files from the target (and I guess I can even use the same name for images, in different directories).
The main thing I'm not sure about are the other configuration variables.
I've heard / thought of a few options:
I think the first option is the fastest to get out of hand once I have a few instances of this app, plus I have to recompile every time I change one of these settings.
The third option I'm also not sure about, because I'll be adding entities to my database which don't feel like they belong there, plus it kind of feels like overkill for what will probably be 5-10 settings. I'm also not sure about how to add new settings on updates.
So I'm leaning more towards the second option.
Thoughts? Any alternatives to these?
UPDATE #1:
Regarding the second option, there is also a drawback that those strings (ids, URLs, etc) will be slightly more exposed (i.e. if someone was to open the app and look through the plist) than if they were in the source code. Not that this is that big of a problem, but it's just something to consider.
Update #2:
How about using the app's info.plist directly and storing it there? (thus having an info.plist for each target configuration) Even though originally I was thinking of having a separate plist, and having a "configuration singleton" which would load everything from there on startup, I think it may be simpler to simply have it in the info.plist and then reading it via [[[NSBundle mainBundle] infoDictionary] objectForKey:@"com.example.mykey1"]
.
Upvotes: 3
Views: 471
Reputation: 7133
I ended up going for the plist, but instead of creating a new one I used the info.plist file for this, thus no need for extra files per target, as I already needed to have a separate info.plist for each one. I simply load them directly from the bundle with:
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"com.example.mykey1"]
I also used preprocessor (with flags set on the target settings) for a couple of things, but that was mostly for when I wanted to disable/remove completely some parts of the app (e.g. to make sure I got everything I commented out enumeration values and even includes in a couple of places).
I think it's relatively clean and I can easily replicate this for future builds without too much of a mess.
Upvotes: 2
Reputation: 14662
I would take the preprocessor option. You can put all your preprocessor in one file/method and it will not be too messy. Like oefe said, change the .sqlite is overkill. And with the multiple plist, you will find yourself dragging things around and doing a lot of error prone actions.
However, I would not make a lot of apps. I would just make one app, let the user select his city at launch. You could also add in-app purchases to let the user add more cities when he wants to.
Upvotes: 4
Reputation: 19916
Given that the variation is per country/region, and these variables are strings, why don't you simply treat them as localizable strings, thus reducing the problem to one already solved?
Otherwise, I would go for the plist. Sqlite seems to be an overkill, and is not source-control friendly. And conditional compilation will get messy fast.
Upvotes: 1