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

时间:2016-09-16 17:32:31

标签: ios iphone ios7

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

例如:我有两个名为 ProjectA ProjectB 的项目。我想嵌入 ProjectA 和< strong> ProjectB 到一个名为 ProjectC 的项目中。 ProjectC 会有条件,具体取决于我必须运行 projectA ProjectB 代码的条件。

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

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

2 个答案:

答案 0 :(得分:10)

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

您可以参考此link

另一种方法是将两个项目放在相同的路径中,创建动态框架并将这些引用用于项目&#39; C&#39;我的意思是你计划的新项目

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

答案 1 :(得分:5)

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

我们说我们已经有了ProjectA和ProjectB。 ProjectC尚未存在,但我们希望ProjectC能够成为一个“组合”的组合。 A和B的位置,其中A或B将根据某些条件运行。运行后,应用程序将继续运行该版本,直到重新启动。

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

我参与了一个项目,我们成功地为大型应用做了你想做的事。我们基本上制作了一个通用应用程序&#34;通过我们的iPhone和iPad项目,结合代码/资产。我们推出了#34;运行时的相应版本。

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

  • 如果您有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&#39; Info.plist将是两者的组合。
  • 提出一个如何应对冲突的策略。例如,当我们遇到冲突的类名时,我们会使用一个命名约定。
  • 将ProjectA和ProjectC源代码/资产添加到项目C中。开始修复冲突。
  • 喝很多咖啡。

您需要控制的其他关键事项之一是根据决定的切入点。如果您可以在UIApplicationMain中致电main.m之前做出决定,则可以执行以下操作:

    Class appDelegate;

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

    }

    return UIApplicationMain(argc, argv, nil, NSStringFromClass(appDelegate));

如果这不起作用,那么您必须在- (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];
}

其中projectAppDelegate设置为您需要的正确版本。

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

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

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

Additional info based on follow up question

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

例如说:

项目A:

typedef NS_ENUM(NSInteger, State) {}

项目B:

typedef NS_ENUM(NSInteger, State) {}

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

  1. ProjectA是&#34;赢家&#34;,因此只有ProjectB会有更改
  2. ProjectB是&#34;赢家&#34;,因此只有ProjectA会有更改
  3. 项目A和项目B都会有变化。
  4. 因此对于1,结果将是

    项目A:

    typedef NS_ENUM(NSInteger, State) {}

    项目B:

    typedef NS_ENUM(NSInteger, PBState) {}

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

    2: 项目A:

    typedef NS_ENUM(NSInteger, PAState) {}

    项目B:

    typedef NS_ENUM(NSInteger, State) {}

    3: 项目A:

    typedef NS_ENUM(NSInteger, PAState) {}

    项目B:

    typedef NS_ENUM(NSInteger, PBState) {}

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

    哦其他一些事情。

    预先投资脚本以查找ProjectA和ProjectB中的所有重复文件。您基本上需要根据所需的扩展(例如.m,.h,.xib等)在ProjectA和ProjectB上执行find。这将为您提供潜在候选人名单,并从那里您可以制定规则战略。

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

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

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