I want to use Xcode 9 to add iOS 11 code to my project while keeping the option to compile the project with Xcode 8 which only supports iOS 10.
In Objective-C I can do t
I understand. I've got an old Mac I like to use that is too old for Xcode 9, so I want to also be able to sometimes compile my projects under Xcode 8.
But if all you want is to support both iOS 10 and iOS 11, the easy way is to just set the minimum SDK of the Xcode target to 10.0, and always compile with the iOS 11 SDK. Swift will work for you in that case, and give you syntax errors unless you correctly use if #available(iOS 11.0, *) {
You'll still be able to test under both iOS 10 and iOS 11 and you won't need to bother with Xcode 8.
From the point of view of Xcode 8, you are trying to compile source code from the future. There's no good solution for Xcode 8.
Going forward, here is the solution:
In Xcode 9.3 (Swift 4.1), you can say:
#if canImport(MagiciOS12Kit)
if #available(iOS 12.0, *) {
MagiciOS12Class.standard.method()
}
#endif
and your code will still compile under Xcode 9.3, but skipping that future stuff that needs a hypothetical Xcode 10.0 or later.
#if canImport(moduleName) was only added in Swift 4.1, which Xcode 8 can't handle. But even this only works for entire modules that Apple adds in the future. If Apple merely extends an existing class with new methods, as in your navigationController.navigationBar.prefersLargeTitles you still won't be able to test for prefersLargeTitles directly, but you can find another framework that Apple introduced at the same time as prefersLargeTitles and check for the existence of that framework with #if canImport(…).