Ответ 1
IOS 11 SDK поставляется с Swift 3.2 (или Swift 4), поэтому вы можете использовать проверку версии Swift для выполнения той же самой задачи:
#if swift(>=3.2)
if #available(iOS 11.0, *) {
…
}
#endif
Я хочу использовать Xcode 9 для добавления кода iOS 11 в мой проект, сохраняя возможность компилировать проект с помощью Xcode 8, который поддерживает только iOS 10.
В Objective-C я могу это сделать, используя директиву препроцессора, чтобы проверить, существует ли __IPHONE_11_0
. Это скроет код, если я компилирую базовый SDK раньше, чем iOS 11. Как это:
#ifdef __IPHONE_11_0
if (@available(iOS 11.0, *)) {
self.navigationController.navigationBar.prefersLargeTitles = YES;
}
#endif
Есть ли способ сделать это в Swift?
if #available(iOS 11.0, *)
не работает, потому что проверка времени выполнения.
IOS 11 SDK поставляется с Swift 3.2 (или Swift 4), поэтому вы можете использовать проверку версии Swift для выполнения той же самой задачи:
#if swift(>=3.2)
if #available(iOS 11.0, *) {
…
}
#endif
Это решение, предложенное Apple:
if #available(iOS 11.0, *) {
// iOS 11 specific stuff here
} else {
// non iOS 11 stuff here
}
Пожалуйста, обратитесь к этому ресурсу (смотрите видео на отметке 6:50 для более подробной информации).
Если вы хотите поместить условие вне функции, вы можете сделать это, как показано ниже.
@available(iOS 11.0, *)
func functionName() {
// function contents
}
Я понимаю. У меня есть старый Mac, который мне нравится использовать, он слишком стар для Xcode 9, поэтому я хочу также иметь возможность иногда компилировать свои проекты под Xcode 8.
Но если все, что вам нужно, это поддерживать iOS 10 и iOS 11, самый простой способ - просто установить минимальный SDK цели Xcode на 10.0 и всегда компилировать с iOS 11 SDK. В этом случае Swift будет работать для вас и выдает синтаксические ошибки, если вы не используете правильно, если #available (iOS 11.0, *) {
Вы по-прежнему сможете тестировать как под iOS 10, так и под iOS 11, и вам не придется беспокоиться о Xcode 8.
С точки зрения Xcode 8, вы пытаетесь скомпилировать исходный код из будущего. Там нет хорошего решения для Xcode 8.
В перспективе вот решение:
В Xcode 9.3 (Swift 4.1) вы можете сказать:
#if canImport(MagiciOS12Kit)
if #available(iOS 12.0, *) {
MagiciOS12Class.standard.method()
}
#endif
и ваш код будет по-прежнему компилироваться в Xcode 9.3, но пропускает тот будущий материал, который нуждается в гипотетическом Xcode 10.0 или более поздней версии.
#if canImport (moduleName) был добавлен только в Swift 4.1, который Xcode 8 не может обработать. Но даже это работает только для целых модулей, которые Apple добавит в будущем. Если Apple просто расширяет существующий класс новыми методами, как в вашем navigationController.navigationBar.prefersLargeTitles, вы все равно не сможете напрямую проверять prefersLargeTitles, но вы можете найти другую платформу, которую Apple представила одновременно с prefersLargeTitles, и проверить существование этого фреймворка с помощью #if canImport (…).
@available(iOS 11.0, *)
func myFunction() {
// function defination
}
if #available(iOS 11.0, *) {
// iOS 11 specific stuff here
} else if #available(iOS 10.0, *) {
// iOS 10 specific stuff here
} else {
// non iOS 11 & 10 stuff here
}