Conditionally import a framework (such as Speech) based on iOS Version in Swift?
Asked Answered
L

2

35

Is there any way to conditionally import a framework in Swift based on runtime iOS version?

In particular, I have an app with a deployment target of iOS 8. I would like to use the new Apple Speech framework in the app, if it is available at runtime. I am aware of the #available(iOS 10, *) directive for code sections, and the @available(iOS 10, *) directive which can be used for an entire class. So I can easily avoid executing any code that uses the Speech framework with those. But in the file that contains the class that uses Speech, I need the "import Speech" statement, and neither of those two directives can be used there. I am finding that even if I have the @available(iOS 10, *) directive on my entire class, when I run my app on an iOS 9 device it is killed at launch with

"dyld: Library not loaded: /System/Library/Frameworks/Speech.framework/Speech".

Am I missing something, or is it only possible to use the Speech framework in an app that has deployment target of 10?

Lucerne answered 23/7, 2016 at 0:24 Comment(0)
U
17

You can make the Framework optional (details and image from Ray Wenderlicht):

Making a framework optional

This, combined with your use of @available, should prevent the system from trying to load it on the devices where it is not available.

Unreason answered 23/7, 2016 at 6:25 Comment(5)
This does not work, at least in this case. Interestingly, in Apple's sample SpeakToMe project, the Speech Framework is not even linked in the project, but it builds and runs fine (on device) anyway. Similarly, in my project, on iOS 10, it works without linking the Speech framework. If I go ahead and add the framework anyway, and make it optional, it still builds and runs on iOS 10, but I get the same crash on iOS 9.Lucerne
@Lucerne Curious. You do need to cover every use of the framework with @ available. Try commenting out the include(s) to cause a compilation error on each one so you can check them - just one parameter use without an @ available will still trigger the system to try to load an 'optional' framework. If not, sorry, that should work afaik.Unreason
Sorry my mistake -- I just realized that I had added the framework to the wrong target in project (we have a lot of targets). So explicitly adding the Speech framework to the correct target, then making it Optional (in combination with @available and #available to avoid the code), does indeed allow the code to run on both iOS 9 and iOS 10.Lucerne
Is this solution working with third-party frameworks too, or only with Apple's ones?Sidestroke
Is there a way to do this for frameworks imported via git? Wrapping the import statement at the top of the file does not workQuartered
C
8

You need to use

#if canImport(YourFramework)
import YourFramework
#endif

instead of @available now, after setting your framework as optional :-)

Cerveny answered 2/11, 2020 at 10:27 Comment(3)
I still got the message: Compiling for iOS 9.0, but module 'ForestCore' has a minimum deployment target of iOS 10.0Organza
canImport works on platform, eg iOS, watchOS, not the version of the OSReddish
Neo, did you find a solution to this?Hamartia

© 2022 - 2024 — McMap. All rights reserved.