#if canImport()未找到带有CocoaPods的框架

时间:2019-03-09 13:32:51

标签: ios swift cocoapods ios-frameworks podspec

您好,这是我们的Podspec,它具有一个default_subspec和一个可选的子规范(由于已经设置了默认值,因此不会使用)。该子规格具有更多功能,但需要额外的8MB大小...

`s.default_subspec = 'mainSDK'

s.subspec 'mainSDK' do |mainSDK|
mainSDK.vendored_frameworks = 'mainSDK.framework'
mainSDK.source_files = "mainSDK.framework/Headers/*.h"
end

s.subspec 'additionalSDK' do |additionalSDK|
additionalSDK.source_files = "additionalSDK.framework/Headers/*.h"
additionalSDK.vendored_frameworks =['additionalSDK.framework', 'mainSDK.framework']
end

现在,在我们的mainSDK中,我们在 #if canImport(additionalSDK)中包括了AdditionalSDK,然后在这些编译器标志之间提供了与AdditionalSDK相关的代码,如下所示:

#if canImport(additionalSDK)
    //adding optional delegate
    class ViewController: UIViewController, OptionalDelagate
#else
    //no need for delagete
    class ViewController: UIViewController
#endif

但是,在客户集成了我们的mainSDK之后,他发现该框架缺少模块: additionalSDK.framework

这怎么可能?我们已经在工作空间中将AdditionalSDK标记为可选。我们尝试在其他链接器标记(构建设置)中将 additionalSDK 设置为 -weak_framework ,但这没有帮助。

如果客户端集成了 additionalSDK ,则一切都会正常运行,因为所有框架都已链接。

可选的依赖项,如果CocoaPods不能很好地工作,那仅仅是CocoaPods的问题,或者我不知道如何配置它

s.platform = :ios
s.ios.deployment_target = '9.0'
s.name = "mainSDK"
s.summary = "mainSDK IOS SDK"
s.requires_arc = true

# 2
s.version = "1.0.8.6.5"

s.source = { :http => "https://s3-eu-west-1.amazonaws.com/zipOfSDK.zip"}
s.framework = "UIKit"

s.source_files = "mainSDK.framework/Headers/*.h"

s.default_subspec = 'mainSDK'

s.subspec 'mainSDK' do |mainSDK|
mainSDK.vendored_frameworks = 'mainSDK.framework'
mainSDK.source_files = "mainSDK.framework/Headers/*.h"
end

s.subspec 'additionalSDK' do |additionalSDK|
additionalSDK.source_files = "additionalSDK.framework/Headers/*.h"
additionalSDK.vendored_frameworks =['additionalSDK.framework', 'mainSDK.framework']
end

s.swift_version = "4.2"

end

2 个答案:

答案 0 :(得分:1)

无法通过说mainSDK是MainTarget,而extraSDK是您的AdditionalTarget来实现这一点?我看到的是,无论您想要什么version,它都只是another target。您可以右键单击原始目标,从当前目标中选择重复目标,然后在“构建阶段”部分中进行所需的更改以链接框架。

#check1:检查您是否use_frameworks!像这样未注释:

# Uncomment this line if you're using Swift
use_frameworks!

#check2:如果确实认为ModuleCache在正确的路径中,请尝试删除Framework。要删除ModuleCache,只需删除~/Library/Developer/Xcode/DerivedData/ModuleCache目录,清除项目并删除特定于项目的派生数据即可。 进行常规清理时,通常不会重建ModuleCache目录。

#check3:检查您的框架以查看其中是否包含带有Modules文件的module.modulemap文件夹(右键单击您的框架>在Finder中显示>确保您的模块映射在其中)

答案 1 :(得分:1)

简短的答案:使用#if canImport(Module)不能实现封闭源代码设置中描述的内容。我对这种条件编译的工作方式有误解。

我的意思是您已经建立了一个框架。似乎#if canImport是在编译时解析的,因此它不是动态的。

当您使用已经预先构建的mainSDK.framework时,部分#if canImport(additionalSDK)已被评估。结果取决于构建链中“ additionalSDK”的可用性(构建时)(因此在机器上准备将其交付给客户时也是如此),而不是在链接时。

我发现有人在这里遇到类似问题:https://flint.tools/blog/finding-a-weak-linking-solution.html

好消息是,您可以使用弱链接和Objective-C互操作性来实现您想要的目标。

与此同时,我正在撰写有关该主题的简短文章,这是一个示例库,该库具有有效的设置,类似于您所描述的要求:

https://github.com/amichnia/Swift-framework-with-optional-frameworks

它支持:

  • AdditionalSDK是可选的
  • MainSDK具有采用AdditionalSDK协议的类
  • MainSDK知道其他功能是否可用
  • 一切都在封闭源代码设置中

更新

我完成了一篇文章,该文章应更详细地描述解决方案。可在https://medium.com/@amichnia_31596/create-a-mostly-swift-framework-with-optional-features-7e8a9ac960f9

获得