Using @available with stored properties

I have this error in Flutter project in XCode 14. One of the external packages were using:

@available(iOS 14.0, *)

My current fix is:

Update version in Podfile platform :ios, '14.0'

Reset pods cd ios && rm -rf Pods/ Podfile.lock && pod install --repo-update

Issue: https://github.com/pichillilorenzo/flutter_inappwebview/issues/1216


Update as of Xcode 14.0.0 beta 1

Unfortunately it seems that lazy properties are now considered stored properties, so this workaround no longer works. Writing your own computed var with backing storage is the best solution for now.

Edit: It turns out that this approach was an error all along, it just didn't produce a diagnostic. That was fixed with Swift 5.7: https://github.com/apple/swift/pull/41112


Previous answer

I know this is an older question but I wanted to add an answer for people who come here via Google as I did.

As kgaidis and Cœur mentioned, you can use @available on computed properties. However, lazy variables are considered computed properties and so you can use @available on them too. This has the nice benefit of removing the boilerplate of the extra stored property and the forced casts - in fact, it leaves no evidence of the property in your pre-iOS 10 code.

You can simply declare it like this:

@available(iOS 10.0, *)
private(set) lazy var center = UNUserNotificationCenter.current()

Unfortunately there's no way to make it completely read-only but the private(set) at least makes it read-only outside of the class.


Here is one potential solution (thanks to blog post). The idea is to use a stored property with a type of Any and then create a computed property that will cast the stored property (and instantiate it if necessary).

private var _selectionFeedbackGenerator: Any? = nil
@available(iOS 10.0, *)
fileprivate var selectionFeedbackGenerator: UISelectionFeedbackGenerator {
    if _selectionFeedbackGenerator == nil {
        _selectionFeedbackGenerator = UISelectionFeedbackGenerator()
    }
    return _selectionFeedbackGenerator as! UISelectionFeedbackGenerator
}

Another option is to use lazy (however, this makes the variable read-write):

@available(iOS 10.0, *)
private(set) lazy var center = UNUserNotificationCenter.current()