objective-c - 从一个框架构建多个 iOS 应用程序

标签 objective-c xcode frameworks

我有一个项目,需要从一个基本应用程序构建一些应用程序。 对于“子应用程序”,它会更改应用程序的 API 凭据、字体、大小、颜色和一些功能。

所以我改变了我的应用程序,我可以轻松地添加功能、更改颜色……通过更改简单的字符串常量来更快地构建新应用程序。


我认为最好的解决方案是向此 XCode 项目添加多个目标,并使用条件编译器标志设置应用程序的单独设置

#ifdef AppTarget1
qr_reader = YES;
#endif

但问题是,将来将会有多个版本的框架可用。因此,当更新基于旧框架的应用程序时,我们总是必须进行调整以使用新版本的框架(如果有),并且我们无法控制框架版本等。

另一个目标是让我们的开发人员使用简单的 Podfile 轻松构建新的应用程序。


因此,下一个想法是创建一个框架项目,然后将其包含在我们的主应用程序中的 CocoaPods 中。我按照这个教程:http://chariotsolutions.com/blog/post/using-cocoapods-to-manage-private-libraries/

在 MainApp 中,我包含了 Framework,MainApp-AppDelegate 类是 Framework-AppDelegate 类的子类。

@interface MainApp_AppDelegate : FrameworkAppDelegate

我设置在 MainApp_AppDelegate 中覆盖的所有基于应用程序的设置的方法。

@implementation MainApp_AppDelegate

-(void)initSettings {
    qr_reader = YES;
}

@end

它就像一种魅力,但我在图像方面遇到了一个问题。 AppFramework包含图像training.png和图像y.png。

在主应用程序 xyz 中,我认为图像training.png 看起来不适合此应用程序,因此我只想更改它(y.png 我希望框架中包含该版本)。我将 x.png 放入主应用程序资源文件夹中,但在编译并运行后,我看到 AppFramework 项目中包含的图像。

training.png what is in the Framework and in the Main App

是否有任何方法可以改变这种行为或更好的方法来创建框架?

最佳答案

发生的事情是 Cocoapods 将其资源复制到最后的 .app您的应用程序完成复制他的应用程序后进行捆绑。所以你的training.jpg被您的框架覆盖。

构建阶段顺序

正如 @masam 所说,您需要重新排序项目的构建阶段,以便在 Cocoapods 资源之后复制应用程序的资源。

Reordering your app build phases

(请注意“复制捆绑资源”现在如何位于列表中的“复制 Pods 资源”下方)

强制资源复制

不幸的是,这还不够,因为 Xcode 的构建系统(试图变得聪明?)不会复制(或在源文件的情况下重新编译)“最新”。对于像图像这样的静态资源,最新意味着目标路径(在最终的 .app 包中)比源路径(在您的 Xcode 项目中)更新。

因此,如果您现在尝试运行应用程序,您将发现没有任何变化。 Xcode 不会复制 training.jpg因为它已经存在并且更新于.app中.

您需要诱骗 Xcode 认为 .app 中的资源已经过时,需要更新。为此,请在“复制 Pods 资源”和“复制捆绑资源”之间添加新的“运行脚本构建阶段”:

the updated build phases with script to outdate resources

脚本应将资源的修改日期设置为较早的日期,以强制 Xcode 复制应用程序的资源。 touch做的工作:

find ${TARGET_BUILD_DIR} -name 'training.jpg' -exec touch -ct $(date -v-1d "+%Y%m%d%H%M.%S") {} \;

我们使用date -v-1d "+%Y%m%d%H%M.%S"将资源的修改日期设置为昨天。

Xcode 现在将使用应用程序的图像覆盖框架的图像。

管理目标资源

再次,正如 @masam 所说,不要忘记仅将资源添加到正确的目标。

例如。

target membership example

这里,应用程序镜像将在 DummyApp 中使用,但 DummyApp2 将使用框架镜像。

结论

tl;dr:尽可能避免这种情况。

  • 对于项目的新手来说,乍一看不可能知道为什么某些目标使用一个文件而不是另一个文件构建;
  • 根据您想要覆盖的框架资源类型,您可能需要维护“重置资源修改时间”脚本(可能通过使 find 更具包容性,例如 find ${TARGET_BUILD_DIR} -name '*.png' );<
  • 更多的是主观意见:我建议不要用您自己的资源隐藏框架中的资源。

关于每个应用程序风格一个目标的事情:

请记住,您对一个目标的构建阶段所做的每一项修改都不会影响其他目标的构建阶段。您需要单独编辑每个目标。因此,我之前的如果可以避免就不要这样做

我完全理解需要有多个目标来构建基于相同代码库的多个应用程序,但 Xcode 在管理大量目标方面非常很糟糕。一位目前正在开发一个相当大的应用程序(1k+ 个文件,以及很多依赖项)且有 65 个不同目标的人说:这是一场噩梦。

.pbxproj基本上会随着目标数量的增加而增长(在我的例子中为 25MB),每次在 Xcode 中完成项目修改时,您都会得到沙滩球。由于每个目标都是独立管理的,因此每次您需要时,例如。添加/删除编译标志,您将需要更新每个目标,一个。经过。一个。 (或者您将使用 .pbxproj/sed/whatever 来“手动”编辑 awk,这更快,但有风险......但很有趣:))。

哦...我有没有提到合并冲突?

关于objective-c - 从一个框架构建多个 iOS 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21415658/

相关文章:

ios - 如果没有更多上下文,表达式类型不明确 - FaveButton Swift 4.2 升级

c++ - 你能推荐一个好的跨平台应用程序开发框架吗?

ios - 调试 Xcode 异常断点;未记录异常 - redux

php - Kohana:有哪些替代方案?

objective-c - 将事件保存到 CalCalendar 是否只存储指向 CalEvent 的指针,而不是副本?

objective-c - 具有 Swift 结构的 C API - 作为 inout 参数的不可变值

ruby - 在 NSMenuItem 对象上调用 setTitle 方法不会更改显示的标题,但会更改属性

ios - 替换已弃用的 .WeekdayCalendarUnit

iphone - 检查 UIWebView 是否滚动到底部

iphone - UINavigationItem:再添加一个按钮