如何从2个嵌入式不同项目中运行项目

kar*_*hik 1 iphone ios ios7

我有两个iOS项目,我想将它作为一个项目,并根据条件一次运行一个项目.

例如:我有2个名为ProjectAProjectB的项目.我想将ProjectAProjectB嵌入到名为ProjectC的单个项目中. ProjectC将具有一个条件,具体取决于我必须运行projectAProjectB代码的条件.

注意:运行项目的条件将在运行时应用,而不是在编译时应用.

我怀疑这真的有可能吗?我需要有关如何解决这个问题的专业知识指导.

vis*_*eja 10

我建议您创建pod并调用您的项目,您可以根据场景/用例调用它,这样您就可以在pod中保留任意数量的项目.

你可以参考这个链接.

另一种方法是将两个项目保持在相同的路径中,创建动态框架并将这些引用用于项目"C"我的意思是您计划的新项目

任何一种方法都可以解决您的问题.


Mob*_*Ben 5

好的,所以基于阅读问题并提出一些问题......我真的不清楚为什么关于豆荚的答案获得了如此多的选票.它没有解决问题.

假设我们已经有了ProjectA和ProjectB.ProjectC尚未存在,但希望使ProjectC成为A和B的"组合",其中A或B将根据某些条件运行.运行后,应用程序将继续运行该版本,直到重新启动.

两种基本方法是将所有代码和资产组合到ProjectC中或尝试创建加载的A和B框架.但是,无论哪种情况,您都将对代码库进行调整.您需要做的工作量也是项目复杂程度的副产品.

我参与了一个项目,我们成功地为大型应用程序做了你想要的东西.我们基本上通过我们的iPhone和iPad项目,结合代码/资产制作了一个"通用应用程序".我们在运行时"启动"了相应的版本.

在你做出这样的努力之前,你需要权衡后果.我列举一些.

  • 如果您有A/B依赖于捆绑ID,那么您将遇到问题.ProjectC将拥有自己的包ID.例如,是否有任何第三方API(例如Facebook)正在使用,您仍希望使用它们,看起来像ProjectA或ProjectB?如果是,但它们与捆绑ID相关联,那么您将遇到问题.
  • 如果您使用的是IAP,那么您的产品ID将需要与众不同.显然,如果这些产品ID是硬编码的,A和B中的代码将需要更改.如果它们是服务器驱动的,您需要确保服务器代码并实际提供正确的产品ID.如果期望ProjectA的所有者仍然应该为ProjectC提供IAP,那么这是可能的......但是,需要花费大小的服务器端逻辑来管理它.
  • 调试代码时你想要多少努力?
  • ProjectA和ProjectB还在积极开发吗?这样做可能会使这些项目之后很难维护.
  • 这个会留出多少时间?这样做很乏味,需要时间.

您可能会将A和B的源/资产组合成C,从而获得更多成功.换句话说,您不会将A或B的项目文件添加到C.为什么?因为您需要能够轻松识别所有冲突点,然后提供解决方法.一个简单的冲突示例是 AppDelegate默认情况下项目创建的内容.你将有3个(A,B,C).

请记住,所有方法都充满了问题.如果您选择框架(无论它们是否是Pod)并且您决定将资产放入框架包中,则必须更改代码才能访问它们,因为它们不再存在于框架中mainBundle.

好的,一般准则是什么?

  • 选择一种方法(例如,组合或框架).我要讨论联合收割机.
  • 尽早确定您的冲突.对于每种类型的冲突,确定您的策略.例如,要解决AppDelegate你可以随时做ProjectAAppDelegateProjectBAppDelegate.
  • 检查一下Info.plist.这是其他冲突的良好来源.C Info.plist将是两者的组合.
  • 想出一个如何处理冲突的策略.例如,当我们遇到冲突的类名时,我们会使用一个命名约定.
  • 将ProjectA和ProjectC源代码/资产添加到项目C中.开始修复冲突.
  • 喝了很多咖啡.

您需要控制的其他关键事项之一是基于决策的入口点.如果你可以在调用之前决定UIApplicationMainmain.m,你可以这样做:

    Class appDelegate;

    if (runA) {
        appDelegate = [ProjectAAppDelegate class];
    } else {
        appDelegate = [ProjectBAppDelegate class];

    }

    return UIApplicationMain(argc, argv, nil, NSStringFromClass(appDelegate));
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,那么你必须这样做- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions.您可能希望将Project C的AppDelegate作为A和B的代理.例如:

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    [self.projectAppDelegate applicationDidBecomeActive:application];
}
Run Code Online (Sandbox Code Playgroud)

哪里projectAppDelegate设置为您需要的正确版本.

请注意,您还需要手动加载故事板以确保启动正确的故事板.请记住,如果你花了很多时间在加载过程中做出决定(你说这是一个网络电话),你的应用程序就可以启动了.

如果它们是框架,您可能能够找到一些漂亮的动态加载,但关键应该是可维护性/易于调试.

我要在这里停下来主要是因为有很多不同的事情要做,我真的没有时间把它们写出来.

Additional info based on follow up question
Run Code Online (Sandbox Code Playgroud)

你有一些文件重复的可能性很高.我举了一个例子AppDelegate.enum会不那么频繁,但会发生.另外请记住,它不是您关心的文件名,而是您关注的类或其他已定义的数据类型.这些是与编译器/链接器有关的冲突.

比如说:

项目A:

typedef NS_ENUM(NSInteger, State) {}

项目B:

typedef NS_ENUM(NSInteger, State) {}

这就是我提前制定战略的意思.示例策略:

  1. ProjectA是"赢家",因此只有ProjectB会有变化
  2. ProjectB是"赢家",因此只有ProjectA会有变化
  3. 项目A和项目B都会有变化.

因此对于1,结果将是

项目A:

typedef NS_ENUM(NSInteger, State) {}

项目B:

typedef NS_ENUM(NSInteger, PBState) {}

请注意我听到的内容.为了让我的生活更轻松,我使用了一些预定义的前缀来指定它是ProjectB.在这种情况下PB.

对于2:ProjectA:

typedef NS_ENUM(NSInteger, PAState) {}

项目B:

typedef NS_ENUM(NSInteger, State) {}

对于3:ProjectA:

typedef NS_ENUM(NSInteger, PAState) {}

项目B:

typedef NS_ENUM(NSInteger, PBState) {}

由你来制定规则,但要保持一致.您将需要一个策略来解决所有数据类型更改的解决方法.例如,如果你要从State- > PBState,你显然只想修改ProjectB.这里有它自己的项目将有所帮助.但是,您可以使用Xcode Search Scope来帮助控制它.

哦其他一些事情.

在前面,投资一个脚本来查找ProjectA和ProjectB中的所有重复文件.您基本上需要find根据所需的扩展(例如.m,.h,.xib等)在ProjectA和ProjectB上执行操作.这将为您提供潜在候选人的列表,并从那里您可以制定规则策略.

由于我是做这部分项目的傻瓜,我基本上将这个列表保存在一个文本文件中.当我合并文件时,我将其移动到文件中的不同部分(由几个换行符分隔).对它进行计算有不同的方法,它只是我选择的方法.

我还要确保你有一个很好的差异工具,如Araxis Merge(这是我使用的).

此外,为了以防万一,请拍摄频繁的快照.你可以使用git分支.我经常只是复制了实际的目录,所以如果需要我可以稍后对它们进行区分