Swift 5 - la version tant attendue, qui comprend plusieurs dizaines d'améliorations et de correctifs. Mais l'objectif principal de la sortie de Swift 5.0 était d'atteindre la stabilité ABI. Dans cet article, vous apprendrez ce qu'est l'ABI et ce qu'ABI stable offrira aux développeurs iOS / macOS. Nous analyserons également plusieurs nouvelles fonctionnalités de Swift 5.

Stabilité ABI
ABI est une interface d'application binaire. Un ABI peut être considéré comme un ensemble de règles qui permettent à un éditeur de liens de combiner des modules de composants compilés.
Par conséquent, ce qui suit est décrit dans ABI.
- La façon dont le code est appelé à partir de différents modules, y compris ceux du système.
- Format pour passer des arguments et obtenir la valeur de retour des fonctions.
- Algorithmes de disposition des données RAM.
- Gestion de la mémoire, ARC.
- Type de système, génériques.
Swift 5, avec ABI stable, offre une compatibilité binaire pour les applications. La compatibilité binaire pour les applications iOS / macOS signifie que les applications compilées seront compatibles à l'exécution avec les bibliothèques système compilées par des versions antérieures ou ultérieures du langage. Par exemple, une application compilée avec Swift 5.0 sera compatible avec les bibliothèques standard compilées avec Swift 5.1 ou Swift 6.0.
À partir d'iOS 12.2 et de macOS 10.14.4, les systèmes d'exploitation d'Apple contiendront tout ce dont vous avez besoin pour exécuter des applications rapides. Cela signifie que les applications écrites dans Swift 5 et versions ultérieures ne contiendront pas d'exécution ni de bibliothèque de langues standard. Par conséquent, les applications écrites dans Swift 5 pèseront environ 3 à 10 mégaoctets de moins.
Il est important de noter qu'en plus de la stabilité ABI, il y a aussi la stabilité du module. Si la stabilité ABI permet de combiner différentes versions d'un swift en runtime, alors la stabilité du module est responsable de la façon dont les frameworks binaires écrits dans différentes versions du langage sont compilés. La stabilité du module apparaîtra dans Swift 5.1. Et puis les développeurs pourront distribuer leurs frameworks non seulement open source, mais aussi sous forme compilée.
Avantages de la stabilité ABI.
- Les applications pèseront moins.
- Accélération des performances de démarrage et d'application.
- En théorie, Apple pourrait écrire de nouveaux cadres entièrement sur Swift.
Contre stabilité ABI.
Les développeurs devront tenir compte de l'absence de toute nouvelle fonctionnalité dans les anciennes versions de la bibliothèque standard. Par exemple, si Swift 5.1 est intégré à iOS 13 avec de nouvelles classes / fonctions dans la bibliothèque standard, alors avec le support dans iOS 12.2, les développeurs ne pourront pas les utiliser. (Vous devrez insérer des vérifications #available (...) de la même manière que nous le faisons actuellement pour Foundation, UIKit et d'autres bibliothèques de plate-forme).
Type de résultat dans la bibliothèque standard
Une manière standard de transmettre et de gérer les erreurs dans l'API asynchrone est apparue dans la bibliothèque standard. Vous pouvez également utiliser ce type si, pour une raison quelconque, la gestion des erreurs standard via try / catch ne nous convient pas.
Le type de résultat est implémenté via enum avec deux cas: succès et échec:
public enum Result<Success, Failure> where Failure: Error { case success(Success) case failure(Failure) ... }
En fait, cette approche n'est pas nouvelle pour les développeurs Swift. Depuis la première version de Swift, de nombreux développeurs ont utilisé une approche similaire. Mais maintenant, lorsque le résultat est apparu dans la bibliothèque standard, cela simplifiera l'interaction avec le code des bibliothèques externes.
Un exemple d'utilisation du service de téléchargement d'articles:
struct Article { let title: String } class ArticleService { func fetchArticle(id: Int64, completion: @escaping (Result<Article, Error>) -> Void) {
Et voici un exemple de traitement du résultat. Puisque Result n'est qu'une énumération, nous pouvons traiter tous ses états avec un commutateur:
articleService.fetchArticle(id: 42) { result in switch result { case .success(let article): print("Success: \(article)") case .failure(let error): print("Failure: \(error)") } }
Chaînes brutes
Dans Swift 5, ils ont ajouté les chaînes dites brutes, dans lesquelles les guillemets et les barres obliques inverses sont interprétés exactement comme des caractères, et pour les utiliser dans un littéral, vous n'avez pas besoin d'utiliser un caractère d'échappement. Pour écrire un littéral pour une telle chaîne, vous devez ajouter le caractère # aux doubles guillemets sur les bords.
Un exemple d'utilisation de guillemets:
Cette fonctionnalité est particulièrement utile lors de l'écriture d'expressions régulières:
Pour interpoler des lignes après une barre oblique inverse, ajoutez le caractère #:
Vous pouvez en lire plus dans cette phrase .
Interpolation de ligne mise à jour
En utilisant l'interpolation de chaîne, nous pouvons ajouter la valeur d'une variable ou le résultat d'une expression à un littéral de chaîne. À partir de la 5e version du langage, il est devenu possible d'élargir la façon dont nos expressions sont ajoutées à la ligne finale.
En général, il suffit d'écrire une extension dans la structure DefaultStringInterpolation et d'ajouter une méthode appelée appendInterpolation. Par exemple, si nous voulons ajouter un prix sous forme formatée à une chaîne:
extension DefaultStringInterpolation { mutating func appendInterpolation(price: Decimal) { let formatter = NumberFormatter() formatter.numberStyle = .currency if let string = formatter.string(from: price as NSDecimalNumber) { appendLiteral(string) } else { appendLiteral(price.description) } } } print("Price of item: \(price: 9.99)")
Il est important de noter qu'en fait, la construction (prix: 9,99) dans la chaîne utilisant le compilateur a été transformée en appel à la méthode appendInterpolation (prix: décimal).
Dans les méthodes appendInterpolation, nous pouvons également ajouter un nombre illimité d'arguments, nommés et non nommés, avec ou sans valeurs par défaut.
Vous pouvez en lire plus dans cette phrase .
Contrôle de multiplicité
La méthode de vérification de la multiplicité isMultiple (of :) a été ajoutée aux types numériques dans la bibliothèque standard. Oui, nous pouvons toujours utiliser l'opérateur pour prendre le reste de la division%. Mais il semble que isMultiple (of :) soit plus visuel.
let interger = 42 if interger.isMultiple(of: 3) { print(" ") } else { print(" ") }
Méthode CompactMapValues dans le dictionnaire
La méthode compactMapValues vous permet de convertir des valeurs de dictionnaire, ainsi que de les filtrer si la conversion elle-même renvoie zéro.
Par exemple, mapper des clés de chaîne à un type d'URL:
let dict = [ "site": "https://www.site.ru/path/to/web/site/page", "other site": "invalid url" ] let mappedDict: [String: URL] = dict.compactMapValues { URL(string: $0) } print(mappedDict)
La deuxième paire clé / valeur a été supprimée après le mappage, car la chaîne n'est pas une URL valide.
Essayez de changer de comportement?
Dans Swift 4.2 en utilisant la construction try? vous pouvez facilement obtenir un type facultatif avec plusieurs niveaux d'imbrication. Dans la plupart des cas, ce n'est pas ce que le développeur attend. Pour cette raison, dans Swift 5 essayez? obtenu un comportement similaire au chaînage facultatif c. Autrement dit, avec une combinaison d'essayer? avec un chaînage ou un cast facultatif, le résultat de l'expression sera facultatif avec un niveau d'imbrication.
Essayez l'exemple? avec comme?:
Essayez l'exemple? avec la méthode d'objet facultative:
Vous pouvez en lire plus dans cette phrase .
Attribut @DynamicCallable
Le nouvel attribut @dynamicCallable vous permet de marquer le type comme "appelable". Cela signifie que nous pouvons appeler le type comme une méthode normale.
Si nous marquons le type comme @dynamicCallable, alors nous devons implémenter l'une (ou les deux) des méthodes:
func dynamicallyCall(withArguments: <#Arguments#>) -> <#R1#> func dynamicallyCall(withKeywordArguments: <#KeywordArguments#>) -> <#R2#>
Le type Arguments doit prendre en charge le protocole ExpressibleByArrayLiteral, le type KeywordArguments doit prendre en charge le protocole ExpressibleByDictionaryLiteral et R1 et R2 peuvent être de n'importe quel type.
Par exemple, la structure de Sum. Lorsque vous l'appelez, vous pouvez transférer n'importe quel nombre de numéros et obtenir leur somme:
@dynamicCallable struct Sum { func dynamicallyCall(withArguments args: [Int]) -> Int { return args.reduce(0, +) } } let sum = Sum() let result = sum(1, 2, 3, 4) print(result)
En fait, le compilateur convertit sum (1, 2, 3, 4) en un appel à sum.dynamicallyCall (withArguments: [1, 2, 3, 4]). De même pour la méthode dynamicallyCall (withKeywordArguments :).
Cette fonctionnalité vous permet d'ajouter l'interaction du code Swift avec divers langages de programmation dynamiques, par exemple, Python ou JavaScript.
Vous pouvez en lire plus dans cette phrase .
Moins de prise en charge des opérateurs dans la version du compilateur et les directives de vérification de la langue
À partir de la 5ème version de Swift, vous pouvez utiliser l'opérateur "less" lors de la vérification de la version du compilateur dans le code:
Conclusion
Ce ne sont pas toutes les fonctionnalités et améliorations qui sont apparues dans Swift 5. Au total, 28 propositions de la communauté ont été acceptées, qui comprenaient également l'amélioration des performances de la ligne, l'amélioration du Swift Package Manager et la bibliothèque standard. Une liste complète des modifications et améliorations peut être trouvée dans les notes de version .