Sur un grand projet, nous avons rencontré une vitesse de construction faible - de trois minutes ou plus. Habituellement, dans de tels cas, les studios pratiquent la modularisation des projets afin de ne pas travailler avec d'énormes monolithes. Chez Surf, nous avons décidé d'expérimenter et de modulariser le projet à l'aide du Swift Package Manager, le gestionnaire de dépendances d'Apple.
Nous parlerons des résultats dans un autre article, mais maintenant nous allons répondre aux principales questions: pourquoi tout cela est-il nécessaire, pourquoi nous avons choisi SPM et comment nous avons fait les premiers pas.
Pourquoi SPM
La réponse est simple - c'est natif et nouveau. Il ne crée pas de frais généraux xcworkspace comme les Cocoapods, par exemple. De plus, SPM est un projet open-source qui se développe activement. Apple et la communauté corrigent des bugs, corrigent des vulnérabilités, se mettent à jour pour suivre Swift.
Est-ce que cela accélÚre la construction du projet
ThĂ©oriquement, l'assemblage va s'accĂ©lĂ©rer du fait mĂȘme de la division de l'application en modules - frameworks. Cela signifie que chaque module ne sera construit que lorsque des modifications y auront Ă©tĂ© apportĂ©es. Mais il ne sera possible de s'affirmer avec certitude qu'Ă la fin de l'expĂ©rience.
Remarque: L'efficacité de la modularisation dépend directement de la division correcte du projet en modules.
Comment faire un partitionnement efficace
La méthode de partitionnement dépend de l'architecture choisie, du type d'application, de sa taille et des plans de développement ultérieur. Par conséquent, je vais parler de trois rÚgles que nous essayons de respecter lors du fractionnement.
Partagez des fonctionnalités génériques. Chaque module est responsable d'une catégorie, par exemple:
- CommonAssets - un ensemble de vos actifs et une interface publique pour y accéder. Il est généralement généré à l'aide de SwiftGen.
- CommonExtensions - un ensemble d'extensions, par exemple Foundation, UIKit, des dépendances supplémentaires.
Flux d'application sĂ©parĂ©s. ConsidĂ©rez une structure arborescente, oĂč MainFlow est le flux principal de l'application. Disons que nous avons une application de nouvelles.
- NewFlow - écrans de nouvelles et aperçu des nouvelles spécifiques.
- FavoritesFlow â .
- SettingsFlow â , , . .
reusable :
- CommonUIComponents â , UI-. .
- UI . , , , . .
Disons que nous avons un flux spécifique et que nous voulons y ajouter de nouvelles fonctions. Si le composant sera réutilisé ou si cela est théoriquement possible à l'avenir, il est préférable de le déplacer dans un module séparé ou un analogue de CommonUIComponents. Dans d'autres cas, vous pouvez laisser le composant local.
Cette approche résout le problÚme des composants manquants. Cela se produit dans les grands projets, et si le composant n'est pas documenté, son support et son débogage deviendront par la suite non rentables.
Créer un projet avec SPM
Envisagez de créer un projet de test trivial. J'utilise un projet d'application multiplateforme sur SwiftUI. La plate-forme et l'interface n'ont pas d'importance ici.
Remarque: pour créer rapidement une application multiplateforme, vous avez besoin de XCode 12.2 beta. Créons un
projet et voyons ce qui suit:
Créons maintenant le premier module commun:
- ajoutez le dossier Frameworks sans créer de répertoire;
- créer un package SPM Common.
- Ajoutez les plates-formes prises en charge au fichier Package.swift. Nous l'avons
platforms: [.iOS(.v14), .macOS(.v10_15)]
- Maintenant, nous ajoutons notre module Ă chaque cible. Nous avons ce SPMExampleProject pour iOS et SPMExampleProject pour macOS.
Remarque: il suffit de connecter uniquement les modules racine aux cibles. Ils ne sont pas ajoutés en tant que sous-modules.
La connexion est terminĂ©e. Il ne vous reste plus qu'Ă configurer un module avec une interface publique - et voilĂ , le premier module est prĂȘt.
Comment ajouter une dépendance pour un package SPM local
Ajoutons le package AdditionalInfo - en tant que Common, mais sans l'ajouter aux cibles. Modifions maintenant le Package.swift du package Common.
Vous n'avez rien d'autre Ă ajouter. Peut ĂȘtre utilisĂ©.
Un exemple proche de la réalité
Connectons SwiftGen à notre projet de test et ajoutons le module Palette - il sera chargé d'accéder à la palette de couleurs approuvée par le concepteur.
- Créez un nouveau module racine en suivant les instructions ci-dessus.
- Ajoutez-y les répertoires racine Scripts et Templates.
- Ajoutez le fichier Palette.xcassets Ă la racine du module et notez tous les jeux de couleurs.
- Ajoutez un fichier Palette.swift vide Ă Sources / Palette.
- Ajoutez le modĂšle palette.stencil au dossier ModĂšles .
- Vous devez maintenant enregistrer le fichier de configuration pour SwiftGen. Pour ce faire, ajoutez le fichier swiftgen.yml dans le dossier Scripts et Ă©crivez ce qui suit:
xcassets:
inputs:
- ${SRCROOT}/Palette/Sources/Palette/Palette.xcassets
outputs:
- templatePath: ${SRCROOT}/Palette/Templates/palette.stencil
params:
bundle: .module
publicAccess: true
output: ${SRCROOT}/Palette/Sources/Palette/Palette.swift
L'apparence finale du
module Palette Nous avons configuré le module Palette . Nous devons maintenant configurer le lancement de SwiftGen pour que la palette soit générée au début de la construction. Pour ce faire, accédez à la configuration de chaque cible et créez une nouvelle phase de construction - appelons-la Générateur de palettes. N'oubliez pas de déplacer cette phase de construction à la position la plus élevée possible.
Maintenant, nous Ă©crivons l'appel pour SwiftGen:
cd ${SRCROOT}/Palette
/usr/bin/xcrun --sdk macosx swift run -c release swiftgen config run --config ./Scripts/swiftgen.yml
Remarque:
/usr/bin/xcrun --sdk macosx
est un préfixe trÚs important. Sans cela, la construction générera une erreur: "impossible de charger la bibliothÚque standard pour la cible 'x86_64-apple-macosx10.15".
Exemple d'appel pour SwiftGen
Done - les couleurs sont accessibles comme ceci:
Palette.myGreen
(Type de couleur dans SwiftUI) et PaletteCore.myGreen
(UIColor / NSColor).
Roches sous-marines
Je vais énumérer ce que nous avons rencontré.
- .
- SwiftLint & SwiftGen SPM. yml.
- Cocoapods. â , SPM . SPM Cocoapods - : «MergeSwiftModule failed with a nonzero exit code». , .
- SPM .
-L$(BUILD_DIR)
.
SPM â Bundler?
Dans ce dossier, je propose de rĂȘver et de discuter dans les commentaires. Le sujet doit ĂȘtre bien Ă©tudiĂ©, mais il semble trĂšs intĂ©ressant. Soit dit en passant, il y a dĂ©jĂ un assez proche intĂ©ressant article sur les avantages et les inconvĂ©nients de SPM.
SPM permet d'appeler swift run en ajoutant Package.swift à la racine de votre projet. Qu'est-ce que ça nous donne? Par exemple, vous pouvez appeler fastlane ou swiftlint. Exemple d'appel:
swift run swiftlint --autocorrect.