'Negate #available statement
I want to execute a code block only on devices running with an OS older than iOS8
. I can't do:
if #available(iOS 8.0, *) == false {
doFoo()
}
The solution I'm using for now is:
if #available(iOS 8.0, *) { } else {
doFoo()
}
, but it feels clunky. Is there another way to negate the #available
statement elegantly with Swift ?
Solution 1:[1]
In Swift 5.6, you can now do the following:
if #unavailable(iOS 15) {
// Under iOS 15
} else {
// iOS 15+
}
Or just the following depending on your case:
if #unavailable(iOS 15) {
// Under iOS 15
}
This is part of SE-0290: Negative availability.
Solution 2:[2]
I use a guard
for this:
guard #available(iOS 8.0, *) else {
// Code for earlier OS
}
There's slight potential for awkwardness since guard
is required to exit the scope, of course. But that's easy to sidestep by putting the whole thing into its own function or method:
func makeABox()
{
let boxSize = .large
self.fixupOnPreOS8()
self.drawBox(sized: boxSize)
}
func fixupOnPreOS8()
{
guard #available(iOS 8, *) else {
// Fix up
return
}
}
which is really easy to remove when you drop support for the earlier system.
Solution 3:[3]
It is not possible to have logic around the #available
statement.
Indeed, the statement is used by the compiler to infer what methods can be called within the scope it embraces, hence nothing can be done at runtime that would conditionally execute the block.
It is possible though to combine conditions, using a comma, as follows
if #available(iOS 8.0, *), myNumber == 2 {
// some code
}
Solution 4:[4]
Seems it's the best solution, before Swift2 you had to use other methods such as using ready-to-use classes wrote by individuals. But that's fine, you can set a variable in viewDidLoad()
and use it to detect the older devices:
var isNewerThan8: Bool = false
func viewDidLoad(){
if #available(iOS 8.0, *) {
isNewerThan8 = true
} else {
isNewerThan8 = false
}
}
func myFunction(){
if isNewerThan8 {
//foo
}else{
//boo
}
}
Solution 5:[5]
Swift 5.6, Xcode 13.3 Beta
if #unavailable(iOS 13, *) {
// below iOS 13
} else {
// iOS 13 and above
}
Swift 5.5 and earlier
a simple way to check is by using #available
with a guard
statement
guard #available(iOS 13, *) else {
// code for earlier versions than iOS 13
return
}
another way is to use if/else
if #available(iOS 13, *) {} else {
// code for earlier versions than iOS 13
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | jscs |
Solution 3 | tomahh |
Solution 4 | Maysam |
Solution 5 |