Objective-C has an expression @availablein Xcode 9+ / LLVM 5+ that allows you to protect a block of code up to at least a certain OS version so that it does not give an unprotected access warning if you use APIs that are available only for that OS version .
The problem is that this availability check is that it only works if it is the only expression in the state if. If you use it in any other context, you will get a warning:
@available does not guard availability here; use if (@available) instead
So, for example, this does not work if you try to perform an availability check with other conditions in if:
if (@available(iOS 11.0, *) && some_condition) {
// code to run when on iOS 11+ and some_condition is true
} else {
// code to run when on older iOS or some_condition is false
}
Any code that uses the iOS 11 API inside the block ifor in some_conditionwill still generate warnings about unprotected accessibility, even if it is guaranteed that these code fragments can only be reached when on iOS 11 +.
I could turn it into two nested ifs, but then the code would elseneed to be duplicated, which is bad (especially if it has a lot of code):
if (@available(iOS 11.0, *)) {
if (some_condition) {
// code to run when on iOS 11+ and some_condition is true
} else {
// code to run when on older iOS or some_condition is false
}
} else {
// code to run when on older iOS or some_condition is false
}
I can avoid duplication by refactoring the block code elseinto an anonymous function, but this requires defining the block elsebefore if, which complicates the code sequence:
void (^elseBlock)(void) = ^{
// code to run when on older iOS or some_condition is false
};
if (@available(iOS 11.0, *)) {
if (some_condition) {
// code to run when on iOS 11+ and some_condition is true
} else {
elseBlock();
}
} else {
elseBlock();
}
Can anyone come up with a better solution?