在封闭源Swift框架中嵌入框架

时间:2015-11-19 05:39:59

标签: ios xcode cocoapods

我们公司希望向我们的客户分发iOS的闭源SDK。我一直在使用Cocoapods构建框架并构建了一个使用它的示例应用程序。以前,该应用程序在模拟器上以及部署在设备上时运行良好。但是,我还在应用程序本身中嵌入了Pods.framework文件。可能感兴趣的另一条信息是框架是用Swift编写的,包含的cocoapods依赖项是Swift和Objective-C。

我想让pods的要求更容易管理,因此用户不需要关心它们并尝试将Pods.framework文件嵌入到我们正在构建的SDK中 - 所以我删除了从示例应用程序中嵌入窗格框架复制窗格资源的步骤,只留在框架中,我还删除了Pods.framework作为示例应用程序的依赖项,只留在SDK中。这似乎可以在模拟器中运行,但应用程序现在在移动设备上崩溃 dyld:未加载库错误。

经过研究,我偶然发现了一些相关的讨论: https://github.com/CocoaPods/CocoaPods/issues/344 https://objectpartners.com/2014/06/25/developing-private-in-house-libraries-with-cocoapods/

但是,使用私有pod的建议解决方案看起来不适合我们,我的理解是私有pod中的源代码仍然是开放的,我们无法共享它与我们的客户。

有人可以就这种情况下可行的解决方案提出建议吗?

1 个答案:

答案 0 :(得分:3)

好的,我终于拥有了更持久的解决方案。现在我已经理解了Xcode如何在我的Swift子框架中更好地链接

使分发/编译有点难看的问题:

由于Swift标准库没有像Obj-C那样捆绑在设备上,它们之间也没有保证稳定(Swift 3承诺的稳定二进制接口:https://github.com/apple/swift-evolution#development-major-version--swift-30)我们必须制作确保整个项目是针对相同版本的Swift编译的。这意味着使用你的闭源框架的人必须在他们的Xcode中为他们的项目使用相同版本的Swift,就像你编译库一样,即使他没有在他的代码中使用Swift,因为最终它&# 39;他的Swift版本被捆绑到应用程序中,你的SDK运行。这只是闭源框架的一个问题,因为开源框架将始终针对与最终项目相同的版本进行编译。可能的解决方法是将客户端限制为您使用的相同版本或分发多个编译(即Swift 2.1和Swift 2.0)。为了解决这个问题,您可以为用户提供针对Swift的多个版本编译的二进制文件的副本。

除此之外,这是我在编译/分发期间必须做的事情,以创建一个在Swift中工作的二进制框架:

构建框架时:

  • 在项目目标中,确保将 Pods.framework 添加到链接的框架和库(确保这是Pods.framework的预编译RED版本,I在同一目录中有一个黑色编译的Pods.framework,它构建得很好,但随后产生了一个框架,导致项目在后续项目的链接器阶段抱怨缺少armv7架构)
  • 在构建设置中的用户定义部分下,添加名为 BITCODE_GENERATION_MODE 的字段并将其设置为 bitcode
  • 不要#import你的桥接标题中的任何框架,所有指示你这样做的指示都是从Swift 1.0-1.2天剩余的,你不再需要它而且它弊大于利(后来的项目会抱怨它找不到那些甚至不会暴露给它的标题。
  • 将构建目标更改为通用iOS设备存档导出框架

使用框架构建项目时:

  • 将框架拖放到项目中,在“常规”选项卡中将其添加到嵌入式二进制文件链接的框架和库(您只需要添加框架本身,而不是子框架或pods文件)
  • 在构建设置标签中,添加框架搜索路径的新路径: $(PROJECT_DIR)/MyFramework.framework/Frameworks
  • 构建项目