I'm trying to add a feature to an existing iOS framework published by my company. The new feature requires that we make use of a number of other, third party-supplied frameworks. We want to ensure that our customers are not required to deploy those frameworks if they do not want to activate the new feature.
I've configured each of these frameworks as Optional when I reference them in the Target / General / Linked Frameworks and Libraries section of my own framework. I also mark them as Optional in the Target / Build Phases / Link Binary With Libraries section of my framework. I'm expecting that this will mean my framework can be imported in an xcodebuild when those frameworks are not present.
This works on the machine where I build my framework, but as soon as anyone else tries to import my new framework their Xcode objects to the import statement with a message "Missing required module 'x'" (where x is the top level third party framework that my framework imports).
I tried removing them and adding linker directives of the form "-weak_framework {name}" to the build, but I can see from the xcodebuild log that the Optional settings simply generate these anyway, and more conveniently.
My framework uses Swift 5, in case it's relevant.
What am I missing?
Many thanks for any clues.
If you create your own framework which uses third party frameworks and you want to make those third party frameworks optional (but at the same time required only for some features of your framework) then I think you need to do few things.
First make sure that those third party frameworks that should be optional use -weak_framework
option for linking. It seems that you already did that. If you are adding those third party frameworks with cocoapods then you will probably need to add at the end of your Podfile script such as the one below because cocoapods tends to override those changes and reverts -weak_framework
to -framework
if you made that change manually.
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
xcconfig_mod = xcconfig.gsub(/-framework "ThirdPartyFrameworkName"/, "-weak_framework \"ThirdPartyFrameworkName\"")
File.open(xcconfig_path, "w") { |file| file << xcconfig_mod }
end
end
end
Second thing is that you will need to import this third party framework in your framework as implementation only framework and you can do this like below:
@_implementationOnly import ThirdPartyFrameworkName
Last thing is that in you code you will need to check if this third party framework is actually loaded so that your code will not crash in case when someone will not add this third party framework to his application. So the optional feature in your framework that uses third party framework should first check for example if given class of this external framework exists before using it like below:
if NSClassFromString("ClassNameFromThirdPartyFramework") == nil {
return // third party framework not available
}
// do something with ClassNameFromThirdPartyFramework here
If you perform all those steps it should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With