Comment faire taire un avertissement en Swift

98

J'ai un morceau de code qui génère beaucoup d'avertissements (API obsolète)

En utilisant clang * je pourrais faire

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    ...
#pragma clang diagnostic pop

Cependant, cela ne fonctionne pas rapidement.

Comment le faire rapidement?

Remarque: je ne veux pas désactiver l'avertissement globalement, ni même à l'échelle du fichier, mais simplement désactiver un avertissement spécifique dans une partie spécifique de mon code source.

Edit: il me semble que ma note n'était pas assez claire: je ne veux PAS de compilation conditionnelle (qui est la réponse proposée du double supposé). Je veux juste faire taire un avertissement SANS utiliser les nouvelles API.

Antzi
la source
duplication possible de l' alternative Swift pour le diagnostic #pragma clang
zrzka
4
Ce n'est pas un doublon. L'autre question ne répond pas à ce problème.
Claus Jørgensen
@ ClausJørgensen en quoi il ne répond pas à ce problème? Il n'y a pas d'autre moyen que celui indiqué dans les réponses à la question liée. Juste une compilation conditionnelle ou une nouvelle #availablemacro où le développeur doit utiliser de nouvelles méthodes et revenir aux anciennes si de nouvelles ne sont pas disponibles.
zrzka
@robertvojta Non, comme le font les réponses, en fait, elles ne disent pas qu'il n'y a pas d'autre moyen de faire taire un avertissement.
Claus Jørgensen
2
Ce n'est pas une dupe. Qu'en est-il d'une situation où vous recevez un avertissement pour avoir manqué un initialiseur?
NSTJ

Réponses:

157

À partir de 2020, Xcode 12.0, le consensus est qu'il n'y a aucun moyen d'y parvenir.

Je mettrai à jour / modifierai cette réponse si Apple ajoute la fonctionnalité.

Mettez-le dans votre liste de souhaits pour la WWDC 2021!

Antzi
la source
21
Merde, c'est une déception. Cela devient parfois incontrôlable . C'est pour le moins ennuyeux.
Isuru
2
Je veux voter contre cette réponse un million de fois, mais cela répond plutôt bien à la question, donc +1 :-)
deadbeef
3
@Isuru À ce moment-là, je serais assez irrité pour tout reconstruire. Je suppose que les avertissements ont fonctionné
Sirènes
1
@Isuru La plupart de ceux-ci devraient être corrigés, pas ignorés.
kevin
3
Si frustrant! Merci d'avoir mis à jour cette réponse.
Dan Loewenherz
48

Il n'y a pas de construction générale pour faire taire les avertissements d'obsolescence dans Swift, mais il existe une solution de contournement qui peut être appliquée dans de nombreux cas .

Disons que vous avez une méthode getLatestImage()sur la classe Fooqui utilise des méthodes / classes obsolètes.

Utilisez @availablecomme Daniel Thorpe l'a décrit pour faire taire tous les avertissements à l' intérieur de la méthode:

@available(iOS, deprecated: 9.0)
func getLatestImage() -> UIImage? {
    ...
}

Vous souhaitez maintenant appeler la méthode getLatestImage()sans avertissement d'obsolescence. Vous pouvez y parvenir en définissant d'abord un protocole et une extension:

private protocol GetLatestImage {
    func getLatestImage() -> UIImage?
}
extension Foo: GetLatestImage {}

Et puis appelez la méthode sans avertissement d'obsolescence (si fooest une instance de Foo):

(foo as GetLatestImage).getLatestImage() // no deprecation warning

Le résultat est que vous avez un code Swift qui utilise une API obsolète sans aucun avertissement de dépréciation.

Tammo Freese
la source
Si intelligent. Une sorte de mal? :) Mais tellement bon. Idéal pour un cas d'utilisation comme la suppression des avertissements sur l'utilisation continue de certains aspects du framework AddressBook qui ont été obsolètes, mais qui ont un remplacement ne fournit pas encore toutes les fonctionnalités requises. Merci.
Duncan Babbage
4
si cela fonctionne, je vous enverrai un pack de six de votre boisson préférée. vous avez un esprit exceptionnel monsieur, merci.
John
@John Merci pour les aimables paroles! Cela fonctionne, j'ai dû le trouver car nous traitons les avertissements comme des erreurs dans notre base de code, et il y a une section qui utilise toujours une bibliothèque obsolète.
Tammo Freese
1
@John lui avez-vous envoyé le pack de six? : P C'est génial. Génie. Merci.
Baran Emre
Vous êtes un mauvais génie.
Krypt
37

En fait, vous pouvez supprimer ces avertissements en utilisant @availabledans la structure logique englobante (c.-à-d. Fonction / type).

Par exemple, supposons que vous ayez du code qui utilise le framework AddressBook, mais que vous construisez avec iOS 9.

@available(iOS, deprecated: 9.0)
func addressBookStatus() -> ABAuthorizationStatus {
    return ABAddressBookGetAuthorizationStatus()
}

À partir de Xcode 7.0.1, cela empêchera l'affichage des avertissements en ligne.

Daniel Thorpe
la source
6
Oui, mais vous verrez le même avertissement lorsque vous appelez votre addressBookStatus()... que vous marquez comme obsolète.
Valentin Shergin
3
Conseil de pro: si vous voulez le faire taire pour une classe entière juste claquer ce petit chien au - dessus de votre déclaration de classe (ex: class ViewController: UIViewController)
Sirènes
2
@Sirens Ensuite, vous verrez cet avertissement chaque fois que vous appelez cette classe ☹️ (au moins avec Xcode 8)
Alexander Vasenin
Quelqu'un a-t-il réussi à faire taire tous les avertissements obsolètes avec ce correctif? J'ai pu réduire leur nombre à un seul , mais je ne vois pas de moyen de me débarrasser du dernier. Aucune suggestion?
Alexander Vasenin
1
Alors, comment utiliser cela pour faire taire l'avertissement «transtyper de 'CGFloat.NativeType' (alias 'Double') en type non lié 'Float' échoue toujours» quand je fais un if CGFloat(0).native is Float { … }? Réponse: Je ne l'utilise pas parce que vous n'avez pas répondu à la question.
Slipp D.Thompson
1

Bien qu'il n'y ait aucun moyen de faire taire les avertissements d'obsolescence dans Swift pour le moment, techniquement, vous pouvez le faire pour un symbole particulier en modifiant le fichier d'en-tête.

  • Copiez le nom du symbole obsolète
  • Sélectionnez File>Open Quickly
  • Collez le symbole et appuyez sur Enter

    Assurez-vous que l'icône Swift est désactivée dans la zone Ouvrir rapidement

  • Sélectionnez File>Show in Finder

  • Modifiez les autorisations de fichier pour autoriser la modification si nécessaire
  • Modifiez les macros d'obsolescence du symbole. Voir les API environnantes pour référence. Par exemple, remplacer:

__OSX_AVAILABLE_BUT_DEPRECATED (__ MAC_10_6, __MAC_10_10, __IPHONE_3_0, __IPHONE_8_0)

avec

__OSX_AVAILABLE_STARTING (__ MAC_10_6, __IPHONE_3_0)

Il y a maintenant un avertissement moins distrayant auquel vous ne pouvez rien faire.

Je sais, c'est sale. Mais s'il n'y a pas d'API de remplacement disponible dans le SDK actuel, cela devrait être sûr. Une fois qu'une nouvelle version de Xcode sortira, la modification sera écrasée et vous verrez à nouveau l'avertissement. Ensuite, vous pouvez tester le nouveau SDK et le nouveau système d'exploitation pour vous assurer que l'API obsolète est toujours disponible et qu'elle n'a pas été remplacée.

Veuillez commenter si vous pouvez trouver des inconvénients.

pointum
la source
Voter pour l'ingéniosité, mais cela laisserait un goût sale dans ma bouche: P
Matt