Swift has provided us quite a few ways to write codes that work for specific platform, version, and language. Examples:
- Run code only for only iOS 13
- Run code only for Swift 5
- Run code only if can import SwiftUI
#available
This is a runtime check, so you can use in regular conditional statements.
if #available(iOS 13.6, macOSApplicationExtension 10.15, *) && someOtherBoolean {
...
} else {
// Fallback code
}
Check out the grammar for details.
The trailing *
denotes that it is available for all other platforms, so that future ones such as glassOS
will be supported, when release.
@available
This is an attribute that applies to types and properties. The grammar is same as #available
.
@available(iOS 12, *)
struct My12Monkeys { ... }
You can also specify for language version:
@available(swift 5) // NOTE: Must be a lower case 's'
func swift5Only() { ... }
You can also annotate more info like this:
@available(iOS, deprecated: 13, message:"No reason", renamed: "Singapore")
struct Singapura { ... }
You can also stack multiple attributes.
Unavailable
It is also important to specify when it is unavailable to a platform. For example, mac does not have dual camera, so this var must not be available when building for mac.
@available(macOS, unavailable)
static var dualCamera: AVCaptureDevice? {
return AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back)
}
canImport()
This tests for modules availability.
#if canImport(SwiftUI)
// SwiftUI code
#else
// Fallback to UIKit
#endif
os(..)
But checking with canImport()
might not be enough. Sometimes, you need to check for the platform. For example, watchOS is often limited.
#if !os(watchOS)
// Not watchOS
#endif