Je reçois
yld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings
et voici la fonction qui provoque l'erreur lorsque l'application est en cours d'exécution sur un périphérique iOS7 et sans même appeler la fonction du tout dans le code.
func reigsterForRemoteUserNotifications(notificationTypes: UIUserNotificationType, categories: NSSet) { let userNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: categories) (UIApplication.sharedApplication()).registerUserNotificationSettings(userNotificationSettings) UIApplication.sharedApplication().registerForRemoteNotifications() }
Je ne veux pas que cette méthode soit accessible du tout lors de l'exécution sur un périphérique iOS7. Je ne veux pas de vérification sélective à l'intérieur car cela signifie que la méthode est disponible pour commencer.
Ce que je veux est un paramètre de configuration de construction pour vérifier la version: Je ne peux pas find un moyen d'écrire une macro préprocesseur équivalent rapide pour vérifier la bonne version iOS et négliger les nouvelles fonctions de bibliothèque iOS 8 non déclarées.
#if giOS8OrGreater // declare the functions that are iOS 8 specific #else // declare the functions that are iOS 7 specific #endif
Dans la documentation Apple propose des fonctions et des generics pour replace les macros complexes, mais dans ce cas, j'ai besoin d'une vérification de compilation précomstack pour éviter de traiter des fonctions non déclarées. Aucune suggestion.
Dans Constants.swift
:
Swift 1:
let Device = UIDevice.currentDevice() private let iosVersion = NSSsortingng(ssortingng: Device.systemVersion).doubleValue
Swift 2:
let Device = UIDevice.currentDevice() private let iosVersion = Double(Device.systemVersion) ?? 0 let iOS8 = iosVersion >= 8 let iOS7 = iosVersion >= 7 && iosVersion < 8
Puis dans d'autres files
if iOS8 { } else { }
Toutes les réponses postées ici sont horribles et ignorent toujours la façon de vérifier la version du système. Vous ne devriez absolument jamais utiliser: Device.systemVersion
Vous ne devriez pas faire de macros personnalisées pour vérifier les numéros de version, et vous ne devriez pas creuser au-delà des bibliothèques qu'Apple a spécifiquement définies pour cette tâche.
Il y a un bon article détaillant cela ici .
Notez que Swift 2.0 vous permet de vérifier directement si un numéro de version d'OS est disponible via:
if #available(iOS 10.0, *) { // modern code } else { // Fallback on earlier versions }
Avant Swift 2.0, l'approche recommandée était via les macros système fournies:
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_9_0) { // do stuff for iOS 9 and newer } else { // do stuff for older versions than iOS 9 }
ou via:
if NSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 10, minorVersion: 0, patchVersion: 0)) { // modern code }
Pour tout ce qui manque au-delà des macros système.
Toute autre approche a été minimisée comme non fiable et non recommandé par Apple. Il y a en fait une approche qui va casser dans iOS 10.
Notez que si vous avez besoin d'une fonctionnalité de type macro dans une vérification et que vous souhaitez utiliser #available
vous pouvez utiliser @available
défini dans cet article en tant que tel:
@available(iOS 7, *) func iOS7Work() { // do stuff if #available(iOS 8, *) { iOS8Work() } } @available(iOS 8, *) func iOS8Work() { // do stuff if #available(iOS 9, *) { iOS9Work() } } @available(iOS 9, *) func iOS9Work() { // do stuff }
Pour plus d'informations sur les attributes dans Swift, vous pouvez consulter la documentation d'Apple .
var systemVersion = UIDevice.currentDevice (). systemVersion
Mise à jour: Ceci est corrigé dans Xcode 6 beta 6 (build 6A280e)
Voici une solution de contournement (peut-être less bonne): lier explicitement à UIKit (je sais que import
instructions d' import
sont déjà liées à des frameworks, mais nous le faisons explicitement de toute façon).
Cela peut entraîner une faible binding entre tous les UIKit, ce qui peut affecter les performances. Pas certain.
En Objective-C, même avec Required, le compilateur lia automatiquement les symboles dont la disponibilité est supérieure à la cible de deployment, et laisse les autres fortement liés. Je ne sais pas pourquoi cela ne fonctionne pas avec Swift.
Selon Apple, il n'y a pas d'appel de préprocesseur dans Swift, mais le code Swift peut être compilé conditionnellement en fonction de l'évaluation des configurations de construction dans deux fonctions. Pour l'instant, nous avons os()
pour OSX ou iOS et arch()
pour un choix de x86_64, arm, arm64 ou i386. Donc, vous pouvez évaluer #if os(iOS)
, mais pas #if os(iOS8)
(bien que cela semble être une bonne idée pour les autres versions de Swift).
Vous pouvez vérifier la version iOS par –
let iosVersion = UIDevice.currentDevice().systemVersion
Et comparez-le en utilisant NSSsortingngCompareOptions.NumericSearch
switch iosVersion.compare("8.0.0", options: NSSsortingngCompareOptions.NumericSearch) { case .OrderedSame, .OrderedDescending: //iOS>=8.0.0 return LAContext() case .OrderedAscending: //iOS<8.0.0 return nil }
Vous pouvez également utiliser les nouvelles API NSProcessInfo, mais elles ne sont pas disponibles pour iOS 7.
if NSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 8, minorVersion: 0, patchVersion: 0)) { //iOS>=8.0.0 }
Vous pouvez voir plus de détails ici . J'espère que cela résout votre requête.
Un post détaillé par le seul et unique: http://nshipster.com/swift-system-version-checking/
Solution pour vérifier la version iOS dans Swift
switch (UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSSsortingngCompareOptions.NumericSearch)) { case .OrderedAscending: println("iOS < 8.0") case .OrderedSame, .OrderedDescending: println("iOS >= 8.0") }
Con de cette solution: il est simplement une mauvaise pratique de vérifier les numéros de version du operating system, de quelque manière que vous le fassiez. On ne devrait jamais coder les dependencies de cette façon, toujours vérifier les caractéristiques, les capacités ou l'existence d'une class. Considère ceci; Apple peut publier une version rétrocompatible d'une class, si c'est le cas, le code que vous proposez ne l'utilisera jamais car votre logique search un numéro de version de operating system et NON l'existence de la class.
( Source de cette information )
Solution pour vérifier l'existence de la class dans Swift
if (objc_getClass("UIAlertController") == nil) { // iOS 7 } else { // iOS 8+ }
N'utilisez pas if (NSClassFromSsortingng("UIAlertController") == nil)
car il fonctionne correctement sur le simulateur iOS en utilisant iOS 7.1 et 8.2, mais si vous testez sur un vrai périphérique en utilisant iOS 7.1, vous remarquerez malheureusement que vous ne passerez jamais à travers la partie else de l'extrait de code.