在闭源 Swift 框架中嵌入框架
Embedding frameworks inside closed-source Swift framework
我们公司想为我们的客户分发 iOS 的闭源 SDK。我一直在使用 Cocoapods 构建框架并构建了一个使用它的示例应用程序。以前,该应用程序在模拟器上以及在设备上部署时都运行良好。但是,我还在应用程序本身中嵌入了 Pods.framework 文件。另一条可能感兴趣的信息是框架是用 Swift 编写的,包含的 cocoapods 依赖项是 Swift 和 Objective-C.
我想让 pods 要求更易于管理,这样用户就不需要关心它们,并尝试将 Pods.framework 文件嵌入到我们正在构建的 SDK 中- 所以我从示例应用程序中删除了 Embed Pods Frameworks 和 Copy Pods Resources 的步骤,只留下它们在框架中,我还删除了 Pods.framework 作为示例应用程序的依赖项,仅将其保留在 SDK 中。这似乎在模拟器中有效,但该应用程序现在在移动设备上崩溃并出现 dyld: Library not loaded 错误。
在研究它时,我偶然发现了一些相关的讨论:
https://github.com/CocoaPods/CocoaPods/issues/344 https://objectpartners.com/2014/06/25/developing-private-in-house-libraries-with-cocoapods/
然而,使用私有的建议解决方案 pods 看起来对我们不起作用,我的理解是私有 pod 中的源代码仍然是开放的,我们无法共享它与我们的客户。
有人可以就适用于这种情况的解决方案提出建议吗?
好的,我终于有了一个更持久的解决方案。它是我旧版本的修改后的更清晰的版本,现在我了解 Swift sub-frameworks 中的 Xcode 链接如何更好
让distribution/compilation有点难看的问题:
因为 Swift 标准库没有像 Obj-C 那样捆绑在设备上,也不保证它们在版本之间是稳定的(Swift 3 中承诺的稳定二进制接口: https://github.com/apple/swift-evolution#development-major-version--swift-30) 我们必须确保整个项目是针对相同版本的 Swift 编译的。这意味着使用您的 closed-source 框架的人必须在他们的 Xcode 中为他们的项目使用相同版本的 Swift ,就像您在编译库时所做的那样,即使他没有使用 Swift 在他的代码中,因为最终是他的 Swift 版本被捆绑到应用程序中并且你的 SDK 运行。这只是 closed-source 框架的问题,因为 open-source 框架将始终针对与最终项目相同的版本进行编译。可能的解决方法是将客户端限制为您使用的相同版本或分发多个编译(即 Swift 2.1 和 Swift 2.0)。为了解决这个问题,您可以为用户提供针对 Swift.
的多个版本编译的二进制文件的副本。
除此之外,这是我在 compilation/distribution 期间必须做的,以制作一个适用于 Swift 的二进制框架:
构建框架时:
- 在项目目标中,确保将 Pods.framework 添加到 Linked Frameworks and Libraries(确保这是 pre-compiled Pods.framework 的 RED 版本,我在同一目录中编译了一个黑色 Pods.framework,它构建得很好,但随后导致了一个框架,该框架会导致项目在链接器阶段抱怨缺少 armv7 架构在后面的项目中)
- 在构建设置中,在 User-Defined 部分下,添加一个名为 BITCODE_GENERATION_MODE 的字段并将其设置为位码
- 不要
#import
桥接中的任何框架 header,所有告诉你这样做的说明都是 Swift 1.0-1.2 天遗留下来的,你不再需要它了而且弊大于利(后面的项目会抱怨找不到这些连接触都没有的header)
- 将构建目标更改为 Generic iOS Device、Archive 和 Export框架
使用框架构建项目时:
- 将框架拖放到项目中,在常规选项卡中将其添加到 Embedded Binaries 和 Linked Frameworks and Libraries(您只需要添加框架本身,而不是 sub-frameworks 或 pods 文件)
- 在 Build Settings 选项卡中,将新路径添加到 Framework Search Paths:$(PROJECT_DIR)/MyFramework。framework/Frameworks
- 构建项目
我们公司想为我们的客户分发 iOS 的闭源 SDK。我一直在使用 Cocoapods 构建框架并构建了一个使用它的示例应用程序。以前,该应用程序在模拟器上以及在设备上部署时都运行良好。但是,我还在应用程序本身中嵌入了 Pods.framework 文件。另一条可能感兴趣的信息是框架是用 Swift 编写的,包含的 cocoapods 依赖项是 Swift 和 Objective-C.
我想让 pods 要求更易于管理,这样用户就不需要关心它们,并尝试将 Pods.framework 文件嵌入到我们正在构建的 SDK 中- 所以我从示例应用程序中删除了 Embed Pods Frameworks 和 Copy Pods Resources 的步骤,只留下它们在框架中,我还删除了 Pods.framework 作为示例应用程序的依赖项,仅将其保留在 SDK 中。这似乎在模拟器中有效,但该应用程序现在在移动设备上崩溃并出现 dyld: Library not loaded 错误。
在研究它时,我偶然发现了一些相关的讨论: https://github.com/CocoaPods/CocoaPods/issues/344 https://objectpartners.com/2014/06/25/developing-private-in-house-libraries-with-cocoapods/
然而,使用私有的建议解决方案 pods 看起来对我们不起作用,我的理解是私有 pod 中的源代码仍然是开放的,我们无法共享它与我们的客户。
有人可以就适用于这种情况的解决方案提出建议吗?
好的,我终于有了一个更持久的解决方案。它是我旧版本的修改后的更清晰的版本,现在我了解 Swift sub-frameworks 中的 Xcode 链接如何更好
让distribution/compilation有点难看的问题:
因为 Swift 标准库没有像 Obj-C 那样捆绑在设备上,也不保证它们在版本之间是稳定的(Swift 3 中承诺的稳定二进制接口: https://github.com/apple/swift-evolution#development-major-version--swift-30) 我们必须确保整个项目是针对相同版本的 Swift 编译的。这意味着使用您的 closed-source 框架的人必须在他们的 Xcode 中为他们的项目使用相同版本的 Swift ,就像您在编译库时所做的那样,即使他没有使用 Swift 在他的代码中,因为最终是他的 Swift 版本被捆绑到应用程序中并且你的 SDK 运行。这只是 closed-source 框架的问题,因为 open-source 框架将始终针对与最终项目相同的版本进行编译。可能的解决方法是将客户端限制为您使用的相同版本或分发多个编译(即 Swift 2.1 和 Swift 2.0)。为了解决这个问题,您可以为用户提供针对 Swift.
的多个版本编译的二进制文件的副本。除此之外,这是我在 compilation/distribution 期间必须做的,以制作一个适用于 Swift 的二进制框架:
构建框架时:
- 在项目目标中,确保将 Pods.framework 添加到 Linked Frameworks and Libraries(确保这是 pre-compiled Pods.framework 的 RED 版本,我在同一目录中编译了一个黑色 Pods.framework,它构建得很好,但随后导致了一个框架,该框架会导致项目在链接器阶段抱怨缺少 armv7 架构在后面的项目中)
- 在构建设置中,在 User-Defined 部分下,添加一个名为 BITCODE_GENERATION_MODE 的字段并将其设置为位码
- 不要
#import
桥接中的任何框架 header,所有告诉你这样做的说明都是 Swift 1.0-1.2 天遗留下来的,你不再需要它了而且弊大于利(后面的项目会抱怨找不到这些连接触都没有的header) - 将构建目标更改为 Generic iOS Device、Archive 和 Export框架
使用框架构建项目时:
- 将框架拖放到项目中,在常规选项卡中将其添加到 Embedded Binaries 和 Linked Frameworks and Libraries(您只需要添加框架本身,而不是 sub-frameworks 或 pods 文件)
- 在 Build Settings 选项卡中,将新路径添加到 Framework Search Paths:$(PROJECT_DIR)/MyFramework。framework/Frameworks
- 构建项目