Bei einem großen Projekt stießen wir auf eine niedrige Erstellungsgeschwindigkeit - von drei Minuten oder mehr. In solchen Fällen üben Studios normalerweise die Modularisierung von Projekten, um nicht mit riesigen Monolithen zu arbeiten. Bei Surf haben wir beschlossen, das Projekt mit dem Swift Package Manager, dem Abhängigkeitsmanager von Apple, zu experimentieren und zu modularisieren.
Wir werden in einem anderen Artikel über die Ergebnisse sprechen, aber jetzt werden wir die Hauptfragen beantworten: Warum wird das alles benötigt, warum haben wir uns für SPM entschieden und wie haben wir die ersten Schritte unternommen?
Warum SPM
Die Antwort ist einfach - es ist einheimisch und neu. Es werden keine xcworkspace-Overheads wie beispielsweise Cocoapods erstellt. Darüber hinaus ist SPM ein Open-Source-Projekt , das sich aktiv weiterentwickelt. Apple und die Community beheben Fehler, beheben Schwachstellen und aktualisieren, um Swift zu folgen.
Beschleunigt dies das Erstellen des Projekts?
Theoretisch wird sich die Assembly beschleunigen, da die Anwendung in Module - Frameworks - unterteilt wird. Dies bedeutet, dass jedes Modul nur erstellt wird, wenn Änderungen daran vorgenommen wurden. Aber es wird möglich sein, erst am Ende des Experiments sicher zu behaupten.
Hinweis: Die Wirksamkeit der Modularisierung hängt direkt von der korrekten Aufteilung des Projekts in Module ab.
So machen Sie eine effiziente Partitionierung
Die Partitionierungsmethode hängt von der gewählten Architektur, der Art der Anwendung, ihrer Größe und den Plänen für die weitere Entwicklung ab. Daher werde ich über drei Regeln sprechen, die wir beim Teilen einhalten wollen.
Teilen Sie allgemeine Funktionen. Jedes Modul ist für eine Kategorie verantwortlich, zum Beispiel:
- CommonAssets - eine Reihe Ihrer Assets und eine öffentliche Schnittstelle für den Zugriff darauf. Es wird normalerweise mit SwiftGen generiert.
- CommonExtensions - Eine Reihe von Erweiterungen, z. B. Foundation, UIKit und zusätzliche Abhängigkeiten.
Separate Anwendungsabläufe. Stellen Sie sich eine Baumstruktur vor, in der MainFlow der Hauptfluss der Anwendung ist. Nehmen wir an, wir haben eine Nachrichtenanwendung.
- NewFlow - Bildschirme mit Nachrichten und Übersicht über bestimmte Nachrichten.
- FavoritesFlow — .
- SettingsFlow — , , . .
reusable :
- CommonUIComponents — , UI-. .
- UI . , , , . .
Nehmen wir an, wir haben einen bestimmten Ablauf und möchten ihm neue Funktionen hinzufügen. Wenn die Komponente wiederverwendet wird oder dies in Zukunft theoretisch möglich ist, ist es besser, sie in ein separates Modul oder ein Analogon von CommonUIComponents zu verschieben. In anderen Fällen können Sie die Komponente lokal belassen.
Dieser Ansatz löst das Problem fehlender Komponenten. Dies geschieht in großen Projekten. Wenn die Komponente nicht dokumentiert ist, werden Wartung und Debugging anschließend unrentabel.
Erstellen Sie ein Projekt mit SPM
Erwägen Sie, ein triviales Testprojekt zu erstellen. Ich verwende das Multiplatform App-Projekt auf SwiftUI. Plattform und Schnittstelle spielen hier keine Rolle.
Hinweis: Um schnell eine Multiplattform-App zu erstellen, benötigen Sie XCode 12.2 Beta. Lassen Sie uns ein
Projekt
erstellen und Folgendes sehen: Jetzt erstellen wir das erste allgemeine Modul:
- Fügen Sie den Frameworks-Ordner hinzu, ohne ein Verzeichnis zu erstellen.
- Erstellen Sie ein allgemeines SPM-Paket.
- Fügen Sie die unterstützten Plattformen zur Datei Package.swift hinzu. Wir haben es
platforms: [.iOS(.v14), .macOS(.v10_15)]
- Jetzt fügen wir jedem Ziel unser Modul hinzu. Wir haben dieses SPMExampleProject für iOS und SPMExampleProject für macOS.
Hinweis: Es reicht aus, nur Root-Module mit den Zielen zu verbinden. Sie werden nicht als Submodule hinzugefügt.
Die Verbindung ist abgeschlossen. Jetzt müssen Sie nur noch ein Modul mit einer öffentlichen Schnittstelle konfigurieren - und voila, das erste Modul ist fertig.
So fügen Sie eine Abhängigkeit für ein lokales SPM-Paket hinzu
Fügen wir das AdditionalInfo-Paket hinzu - als Common, ohne es jedoch den Zielen hinzuzufügen. Ändern wir nun die Package.swift des Common-Pakets.
Sie müssen nichts weiter hinzufügen. Kann verwendet werden.
Ein realitätsnahes Beispiel
Verbinden wir SwiftGen mit unserem Testprojekt und fügen das Palettenmodul hinzu - es ist für den Zugriff auf die vom Designer genehmigte Farbpalette verantwortlich.
- Erstellen Sie ein neues Root-Modul gemäß den obigen Anweisungen.
- Fügen Sie die Stammverzeichnisse für Skripte und Vorlagen hinzu.
- Fügen Sie die Datei Palette.xcassets zum Modulstamm hinzu und notieren Sie alle Farbsätze.
- Fügen Sie Sources / Palette eine leere Palette.swift-Datei hinzu.
- Fügen Sie die Vorlage palette.stencil zum Ordner Vorlagen hinzu .
- Jetzt müssen Sie die Konfigurationsdatei für SwiftGen registrieren. Fügen Sie dazu die Datei swiftgen.yml zum Ordner Scripts hinzu und schreiben Sie Folgendes hinein:
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
Das endgültige Erscheinungsbild des Palettenmoduls
Wir haben das Palettenmodul konfiguriert. Jetzt müssen wir den Start von SwiftGen so konfigurieren, dass die Palette zu Beginn des Builds generiert wird. Gehen Sie dazu zur Konfiguration jedes Ziels und erstellen Sie eine neue Erstellungsphase - nennen wir sie Palettengenerator. Vergessen Sie nicht, diese Build-Phase auf die höchstmögliche Position zu verschieben.
Jetzt schreiben wir den Aufruf für SwiftGen:
cd ${SRCROOT}/Palette
/usr/bin/xcrun --sdk macosx swift run -c release swiftgen config run --config ./Scripts/swiftgen.yml
Hinweis:
/usr/bin/xcrun --sdk macosxist ein sehr wichtiges Präfix. Ohne diese Option generiert der Build einen Fehler: "Standardbibliothek für Ziel 'x86_64-apple-macosx10.15 kann nicht geladen werden".
Beispielaufruf für SwiftGen
Fertig - Auf Farben kann wie folgt zugegriffen werden:
Palette.myGreen(Farbtyp in SwiftUI) und PaletteCore.myGreen(UIColor / NSColor).
Unterwasserfelsen
Ich werde auflisten, was uns begegnet ist.
- .
- SwiftLint & SwiftGen SPM. yml.
- Cocoapods. — , SPM . SPM Cocoapods - : «MergeSwiftModule failed with a nonzero exit code». , .
- SPM .
-L$(BUILD_DIR).
SPM — Bundler?
In dieser Angelegenheit schlage ich vor, in den Kommentaren zu träumen und zu diskutieren. Das Thema muss gut studiert werden, aber es sieht sehr interessant aus. Übrigens gibt es bereits einen interessanten, ziemlich engen Artikel über die Vor- und Nachteile von SPM.
Mit SPM können Sie Swift Run aufrufen, indem Sie Package.swift zu Ihrem Projektstamm hinzufügen. Was gibt es uns? Sie können beispielsweise Fastlane oder Swiftlint aufrufen. Beispiel aufrufen:
swift run swiftlint --autocorrect.