问题描述
我正在使用Swift Package Manager
将应用程序模块化,方法是将应用程序的各个部分分成不同的层(包):表示,业务和数据,以使其尽可能简洁,并链接这些手动创建的包在项目设置->框架,库和嵌入式内容部分中查看该项目。但是,在项目的某些部分中我仍然需要Cocoa Pods
,为简单起见,我的pod文件包含以下内容:
target 'SampleApp' do
use_frameworks!
pod 'Localize-Swift'
end
当我将Localize-Swift
导入这些软件包的源文件之一时,出现错误:No such module
,但是Pods导入在应用程序的非打包部分(如SceneDelegate
)中工作得很好。
我知道SPM
依赖项必须仅是Swift软件包,但是是否有任何已知的解决方法将pod链接到swift软件包中?
解决方法
这是可能的,但它没有用,因为Swift程序包没有像XCode项目使用-weak_framework <framework_name>
那样弱地链接到框架,因此您需要实施一些不重要的步骤。
在swift包中,您可以指定要与linkedFramework
链接的框架:
.target(
name: "MyPackage",dependencies: [],linkerSettings: [
.linkedFramework("Localize_Swift")
.unsafeFlags(["-F/Users/user/.../Localize-Swift"])
]
),
其中unsafeFlags
指定框架的dir的完整路径。但是出乎意料的是,由于下一个问题,您不能将包与您的应用程序一起使用:
包装产品“ MyPackage”不能用作此产品的依赖项 目标,因为它使用了不安全的构建标志。
要使用您的框架编译Swift软件包,您应该将Localize_Swift.framework复制到目标软件包的构建目录,然后可以省略该软件包的不安全构建标志,因为编译器会在该目录的根目录下看到所有依赖项。
.target(
name: "MyPackage",linkerSettings: [
.linkedFramework("Localize_Swift")
]
),
添加软件包后,您可以对应用执行相同操作。如果将Localize_Swift.framework复制到应用程序的目标构建目录中,则可以编译链接的swift软件包,因为它会在当前构建目录中寻找linkedFramework
。
默认情况下,系统会在目标构建目录中生成默认Pod来分隔文件夹,例如:$TARGET_BUILD_DIR/Localize-Swift/Localize_Swift.framework
,因此您可以在Pods项目中为CONFIGURATION_BUILD_DIR
目标更改Localise-Swift
,以将框架生成到目标构建目录或制作要复制的脚本等。但是,当您没有任何已编译的pod框架时,便会在编译过程的早期开始就开始快速编译软件包依赖项。因此,在第一阶段,您应该先编译Localize_Swift.framework(最好制作一个胖的框架),然后在目标架构的Pre-actions
下添加Run Script
Build
,以从您的目标是目标构建目录。
cp -r $PROJECT_DIR/Localize_Swift.framework $TARGET_BUILD_DIR/Localize_Swift.framework
现在,您的应用程序和swift包都可以使用Localize_Swift框架进行编译了。
正如我在一开始所说的那样,它没有用,因为您需要在常规编译过程之前手动(或使用其他脚本)编译Localize_Swift.framework,以完全抵消可可豆的便利性。
考虑使用下一个首选选项:
- Pod可以作为快速包提供。您可以在包中建立依赖关系,在这种情况下,您的包和依赖关系也将在您的应用程序中可用。顺便说一下Localize_Swift支持swift软件包。
-
Pod具有快速的源代码。您可以使用源文件制作自己的swift软件包,然后将其链接到您的软件包。
-
Pod具有二进制文件。从Swift 5.3中可以将swift软件包嵌入
xcframework
,因此您可以从pod的二进制文件构建此xcframework,然后在swift软件包中建立二进制目标依赖项:{{ 1}}(请参阅How can I add a local library as a dependency in Swift Package Manager)