管理一系列相关 iOS 应用程序的最佳实践
我目前正在将现有的 iOS 应用程序改编为一系列非常相似的应用程序(每个应用程序实例可能会映射到不同的国家/地区)。
我计划为每个实例设置不同的构建目标,它们之间的唯一区别应该是:
- 图像(可能只是启动屏幕和图标)
- 本地化
- 字符串变量:远程服务的基本 URL、应用程序 ID、支持 e-邮件等(可能有六个这样的变量)
代码本身在所有应用程序上应该是相同的。
我想知道您认为管理此类应用程序系列的最佳实践是什么。
关于图像和本地化(或一般的资源),它应该只是从目标添加/删除适当的文件的问题(我想我什至可以在不同的目录中对图像使用相同的名称)。
我不确定的主要是其他配置变量。
我听说/想到了几个选项:
- 使用预处理器宏和具有不同 URL、ID 等的主配置头文件
- 每当应用程序启动时从 plist(或类似的配置文件)加载它们,并且每个文件都有一个这样的文件target
- 创建一个空的 .sqlite 文件(这个应用程序已经使用 Core Data)并用默认配置变量填充它,并且每个目标都有一个这样的文件
我认为一旦我有几个实例,第一个选项是最快失控的这个应用程序的,而且每次更改这些设置之一时我都必须重新编译。
我也不确定第三个选项,因为我将向我的数据库添加实体,这些实体感觉不属于那里,而且对于可能有 5-10 个设置的感觉有点矫枉过正。我也不确定如何在更新中添加新设置。
所以我更倾向于第二种选择。
想法?除了这些还有其他选择吗?
更新 #1:
关于第二个选项,还有一个缺点,即这些字符串(id、URL 等)会比它们在源代码。这并不是什么大问题,但这只是需要考虑的事情。
更新 #2:
直接使用应用程序的 info.plist 并将其存储在那里怎么样? (因此为每个目标配置都有一个 info.plist)尽管最初我正在考虑拥有一个单独的 plist,并拥有一个“配置单例”,它将在启动时从那里加载所有内容,但我认为简单地拥有它可能会更简单在 info.plist 中,然后通过 [[[NSBundle mainBundle] infoDictionary] objectForKey:@"com.example.mykey1"]
读取它。
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:
- Images (probably just the splashscreen and icons)
- Localizations
- String variables: base URL for remote services, application ID, support e-mails, etc (possibly half a dozen of such variables)
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:
- Using preprocessor macros and a main configuration header file with the different URLs, IDs, etc
- Loading them from a plist (or similar configuration file) whenever the application launches, and having one such file per target
- Creating an empty .sqlite file (this app already uses Core Data) and populating it with the default configuration variables, and having one such file per target
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"]
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我会选择预处理器选项。您可以将所有预处理器放在一个文件/方法中,并且不会太混乱。就像 oefe 所说,更改 .sqlite 是矫枉过正。对于多个 plist,您会发现自己在拖拽东西并执行许多容易出错的操作。
但是,我不会制作很多应用程序。我只会制作一个应用程序,让用户在启动时选择他的城市。您还可以添加应用内购买,以便用户在需要时添加更多城市。
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.
我最终选择了 plist,但我没有创建一个新的 plist,而是使用了 info.plist 文件,因此每个目标不需要额外的文件,因为我已经需要为每个目标都有一个单独的 info.plist。我只是直接从捆绑包中加载它们:
我还使用了预处理器(在目标设置上设置了标志)来做一些事情,但这主要是当我想完全禁用/删除应用程序的某些部分时(例如,确保我得到了我注释掉的所有枚举值,甚至包括在几个地方)。
我认为它相对干净,我可以轻松地在未来的构建中复制它,而不会造成太多混乱。
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:
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.
鉴于每个国家/地区都有差异,并且这些变量是字符串,为什么不简单地将它们视为可本地化的字符串,从而将问题减少到已经解决的问题?
否则,我会去plist。 Sqlite 似乎有点矫枉过正,而且对源代码控制不友好。而且条件编译很快就会变得混乱。
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.