Using a pod from inside a swift package

半腔热情 提交于 2021-01-27 19:35:08

问题


I'm making my app modularized using Swift Package Manager by separating various parts of the app into different layers (packages): Presentation, Business and Data to make it as clean as possible, and I link those manually created packages with the project in project settings -> Frameworks, Libraries and Embedded Content section. However, I'm still in need for Cocoa Pods in some parts of the project, for simplicity my pod file contains the following:

target 'SampleApp' do
  use_frameworks!
  
  pod 'Localize-Swift'
end

when I import the Localize-Swift into one of those packages' source files I get the error: No such module, however Pods import works well in non-packaged parts of the app like SceneDelegate. I know that SPM dependencies must be Swift Packages only, but is there any known workaround to link pods into swift packages ?


回答1:


It's possible but it's not useful because Swift Packages don't have weak linking to frameworks as XCode project does with -weak_framework <framework_name> so you need to implement non trivial steps.

In swift package you can specify a framework to link with linkedFramework:

.target(
    name: "MyPackage",
    dependencies: [],
    linkerSettings: [
        .linkedFramework("Localize_Swift")
        .unsafeFlags(["-F/Users/user/.../Localize-Swift"])
    ]
),

Where unsafeFlags specifies the full path to dir with the framework. But unexpectedly then you can not use your package with your app because of next issue:

The package product 'MyPackage' cannot be used as a dependency of this target because it uses unsafe build flags.

To compile Swift Package with your framework you should copy Localize_Swift.framework to target build dir of your package and then you can omit unsafe build flags of the package because the compiler sees all dependencies on the dir's root level.

.target(
    name: "MyPackage",
    dependencies: [],
    linkerSettings: [
        .linkedFramework("Localize_Swift")
    ]
),

The same you can do with your app after adding your package. If you copy Localize_Swift.framework to the app's target build dir then your linked swift package can be compiled because it looks for linkedFramework in the current build dir.

By default pods are generated to separate folders in target build dir e.g.: $TARGET_BUILD_DIR/Localize-Swift/Localize_Swift.framework so you can change CONFIGURATION_BUILD_DIR for Localise-Swift target in Pods project to generate the framework to the root of the target build dir or make a script to copy etc. But there is a problem that swift package dependencies are started compiling at the early begin of compilation process when you don't have any compiled pod frameworks. So at the first stage you should compile your Localize_Swift.framework before (better to make a fat framework) and then add a Pre-actions Run Script under Build in your target scheme that copies the framework from your destination to target build dir.

cp -r $PROJECT_DIR/Localize_Swift.framework $TARGET_BUILD_DIR/Localize_Swift.framework

Now both your app and your swift package can be compiled with Localize_Swift framework.

As I say in the begin it's not useful because you need to compile Localize_Swift.framework manually (or with an additional script) before the general compilation process that neutralizes convenience of cocoa pods at all.

Consider using next preferred options:

  1. Pod is avaliable as a swift package. You can make a dependency in your package and in this case both your package and the dependency will be also available in your app. By the way Localize_Swift supports swift packages.
  1. Pod has swift sources You can make your own swift package with the sources files and then link it to your package.

  2. Pod has binaries From Swift 5.3 swift package can embed xcframework so you can build this xcframework from pod's binaries and then make binary target dependency in your swift package: .binaryTarget(name: "MyLib", path: "MyLib.xcframework") (see How can I add a local library as a dependency in Swift Package Manager)



来源:https://stackoverflow.com/questions/63700091/using-a-pod-from-inside-a-swift-package

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!