Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
185 views
in Technique[技术] by (71.8m points)

ios - #if canImport() does not find frameworks with CocoaPods

Hello here is our Podspec which has a default_subspec and an optional subspec (which won't be taken since the default is already set). That subspec has more features, but takes an additional 8MB of size...

`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

Now, in our mainSDK we include additionalSDK with #if canImport(additionalSDK) We then provide code related to additionalSDK in between those compiler flags, like this:

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

However, after client integrates our mainSDK he sees that this framework is missing module: additionalSDK.framework

How is this possible? We have marked additionalSDK as optional in our workspace. We have tried to set additionalSDK as a -weak_framework in other linker flags(Build settings) , but this did not helped.

If client integrates additionalSDK everything works well, because all frameworks are linked..

Optional dependencies, without CocoaPods work well, it is just problem of CocoaPods or I don't know how to configure it

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Short answer: Using #if canImport(Module) would not allow you to achieve what you described in a closed source setup. I see some misunderstanding of how this conditional compilation works.

What I mean is that you've already built a framework. Seems that #if canImport is resolved at a compile time, so it is not dynamic.

When you use already prebuilt mainSDK.framework, the part #if canImport(additionalSDK) was already evaluated. And the result depends on the availability of 'additionalSDK' in the build chain, when it was built (so on your machine when you prepare it for shipping to clients), not when it is linked.

I found someone struggling with a similar issue here: https://flint.tools/blog/finding-a-weak-linking-solution.html

The good news is, that what you want to achieve is possible using weak linking and objective-C interoperability.

I'm working on a short article about the topic, in the meantime, here is an example repository with a working setup, similar to what you described as requirements:

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

It supports:

  • AdditionalSDK is optional
  • MainSDK have classes adopting AdditionalSDK's protocols
  • MainSDK knows if additional features are available
  • It is all in closed source setup

Update:

I finished an article, which should describe the solution in more details. It is available at https://medium.com/@amichnia_31596/create-a-mostly-swift-framework-with-optional-features-7e8a9ac960f9


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...