How do I do weak linking in Swift?
Seems like I've figured out what you can do
I used
NSClassFromString()
to check if class is available on device, i.e.if NSClassFromString("UIBlurEffect") { let blur = UIBlurEffect(...) //...}else { //...}
It's needed to make
UIKit.framework
(or another corresponding framework) optional. If you create Swift-based application in XCode6-BetaX, all the frameworks wouldn't be explicitly added to the link build phase so you need to go to your target settings, addUIKit.framework
as a linked framework (in 'Link Binary With Libraries' section) and to change its status toOptional
. This step does the trick and I've managed to run version specific code without a problem.
Update: You don't need to make it optional anymore, since Xcode 6 beta 6 (via @user102008)
Update 2: You can't actually perform implicit if statement checks for nil (since Xcode 6 Beta 5). You need to assert it like that:
if NSClassFromString("UIBlurEffect") != nil { let blur = UIBlurEffect(...) //... } else { //... }
(via @daniel-galasko)
Just to add my two cents since I ended up using this to my immediate dismay upon distributing the app to our testers. There is a bug in the Swift compiler (Xcode <= 6.1.1) whereby when building in Release mode the compiler actually doesn't return nil when calling NSClassFromString
.
To check me simply change your configuration to Release and see how she crashes.
I ended up having to explicitly check for iOS versions or a simple respondsToSelector call in other place.
So where my code looked like this:
if NSClassFromString("UIVisualEffectView") != nil { //use the blur safely } else { //abandon blur! try something safer }
I ended up having to use this instead
switch UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch) { case .OrderedSame, .OrderedDescending: //go wild with blur case .OrderedAscending: //blur shall not pass here! }
This question dealt with the same issue - UIAlertView is crashing app on iOS 7