Zum Hauptinhalt springen

Verwenden Sie SPM-Paketmerkmale in Capacitor 8

Verwenden Sie SPM-Paketmerkmale in Capacitor 8: Aktivieren Sie optionalen Pluginfunktionen mit packageTraits, setzen Sie die Swift-Tools-Version auf 6.1 und fügen Sie Merkmale Ihrem eigenen Plugin hinzu.

Martin Donadieu

Martin Donadieu

Writer

Valeria

Rezensent

Jordan

Redakteur

Wie man SPM-Paketmerkmale in Capacitor 8 verwendet

Um SPM-Paketmerkmale in Capacitor 8 zu verwenden, stellen Sie experimental.ios.spm.swiftToolsVersion zu "6.1" und listet die Merkmale pro Plugin auf experimental.ios.spm.packageTraits in your Capacitor config, then run bunx cap sync iosDie CLI schreibt diese Merkmale in die generierte CapApp-SPM/Package.swift, und SwiftPM baut das Plugin mit den passenden optionalen Abhängigkeiten und code Pfaden auf. Dies erfordert Capacitor CLI 8.3.0 oder höher und gilt nur für iOS-Projekte, die den Swift Package Manager verwenden.

Funktionalitäten schließen den letzten großen Funktionsunterschied zwischen SPM und CocoaPods für Plugins: optional native Abhängigkeiten, die früher als podspec-Unterspecs verwendet wurden. Diese Anleitung umfasst die App-Seite, die Seite des Plugin-Autors und die Grenzen der aktuellen experimentellen Unterstützung.

Was sind Paketmerkmale?

Paketmerkmale stammen aus dem Swift-Evolution-Vorschlag SE-0450 SE-0450, implementiert in Swift 6.1 (Xcode 16.3 und später). Ein Paket erklärt benannte Merkmale in seinem Package.swiftVerbraucher wählen welche aus, wenn sie auf das Paket abhängen. Ein Merkmal kann:

  • eine Abhängigkeit optional machen (condition: .when(traits: [...]) auf eine Zielabhängigkeit)
  • Aktivieren Sie code Pfade, da jede aktivierte Eigenschaft als Kompilationsbedingung verfügbar ist.#if TraitName),
  • toggle Build-Einstellungen wie Defines oder Linker-Flags.
  • andere Merkmale aktivieren

Ein Paket kann auch Merkmale als Standard markieren. Sie sind an, bis der Verbraucher eine explizite Liste übergeben hat.

Wenn Sie CocoaPods-Subspezifik oder Cargo-Funktionen in Rust kennen, ist es das gleiche Konzept.

Why es es wichtig in Capacitor

Capacitor generiert die Anwendung Package.swift Für Sie, damit Sie die Abhängigkeitszeilen nicht manuell bearbeiten können. Vor CLI 8.3 hatten Pluginautoren mit einer optionalen nativen SDK zwei schlechte Wahlmöglichkeiten bei SPM: Sie mussten entweder immer die SDK verlinken, was zu einem Größenzuwachs und manchmal zu zusätzlichen Datenschutz- oder Exportkonzessionarbeiten führte, oder ein zweites Plugin veröffentlichen. Häufige Fälle:

  • verschlüsselte vs. unverschlüsselte SQLite (SQLCipher)
  • Analyse-SDKs mit und ohne Sammlung des Werbeidentifikators
  • eine optionale Vendor-SDK für einen Zahlungs- oder Anmeldeanbieter
  • Debug-Only-Tooling

Traits in Ihrer App aktivieren

1. Überprüfen Sie die Versionen

bunx cap --version      # 8.3.0 or later
xcodebuild -version     # Xcode 26 (required by Capacitor 8 anyway)

Die Projekt muss SPM verwenden: ios/App/CapApp-SPM existiert. Wenn Sie auf CocoaPods sind, sehen Sie wie Sie Ihre Capacitor-Anwendung auf SPM migrieren können.

2. Finden Sie die Plugin-Trait-Namen

Öffnen Sie das Plugin’s Package.swift in node_modules und suchen Sie nach dem traits: Array, oder überprüfen Sie dessen README. Die Trait-Namen sind case-sensitive.

3. Konfigurieren Sie Capacitor

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.example.app',
  appName: 'Example',
  webDir: 'dist',
  experimental: {
    ios: {
      spm: {
        swiftToolsVersion: '6.1',
        packageTraits: {
          '@acme/capacitor-db': ['.defaults', 'SQLCipher'],
        },
      },
    },
  },
};

export default config;

Die Schlüsselwort ist das Plugin’s npm Paketname. Der Wert ist die Liste der zu aktivierenden Traits.

4. Synchronisieren und überprüfen Sie die Ausgabe

bunx cap sync ios

Die generierte ios/App/CapApp-SPM/Package.swift jetzt beginnt mit // swift-tools-version: 6.1 und die Plugin-Abhängigkeitszeile trägt die Traits:

.package(name: "AcmeCapacitorDb", path: "../../../node_modules/@acme/capacitor-db", traits: [.defaults, "SQLCipher"])

Das CLI schreibt .defaults (oder defaults, .default, default in jedem Fall) als der SwiftPM .defaults Wert und jedes andere Name als ein Zitatsatz.

Bauen Sie in Xcode. Wenn Xcode immer noch die alte Grafik anzeigt, verwenden Sie Datei > Pakete > Paket-Caches zurücksetzen.

Regeln, die CLI durchsetzt

Die Capacitor CLI überprüft die Konfiguration während der Synchronisierung:

  • Wenn ein Plugin eine nicht leere Liste von Merkmalen hat und swiftToolsVersion fehlt, wird die Synchronisierung mit „Paketmerkmale erfordern eine explizite Swift-Tools-Version von 6.1 oder höher.“ abgebrochen.
  • Wenn swiftToolsVersion Die Version ist zu niedrig, daher wird die Synchronisation abgebrochen.
  • swiftToolsVersion muss wie aussehen 6.1 oder 6.1.0.
  • Plugins mit einer leeren Array werden als nicht aufgelistet behandelt.

Halten Sie die Standardmerkmale oder streichen Sie sie

Die Auflistung von Merkmalen ersetzt die Standards. Vergleichen Sie:

Wert der Konfiguration Ergebnis
nicht aufgelistet Standardmerkmale des Plugins
['SQLCipher'] nur SQLCipher, Standards aus
['.defaults', 'SQLCipher'] Standards plus SQLCipher

Lesen Sie die Dokumentation des Plugins, bevor Sie Standards streichen. Ein Plugin könnte seinen Standard-Backend hinter einem Standardmerkmal platzieren.

Zu Ihren eigenen Plugins Eigenschaften hinzufügen

Wenn Sie ein Plugin mit einem optionalen SDK pflegen, hier ist eine vollständige Anleitung Package.swiftDie Paketname muss dem Namen entsprechen, den Capacitor CLI aus Ihrem npm-Name ableitet (@acme/capacitor-db wird AcmeCapacitorDbSiehe migrieren Sie ein Capacitor-Plugin zu SPM für die Regel.

// swift-tools-version: 6.1
import PackageDescription

let package = Package(
    name: "AcmeCapacitorDb",
    platforms: [.iOS(.v15)],
    products: [
        .library(name: "AcmeCapacitorDb", targets: ["DbPlugin"])
    ],
    traits: [
        .trait(name: "SQLCipher", description: "Link SQLCipher and enable encrypted databases."),
        .default(enabledTraits: [])
    ],
    dependencies: [
        .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0"),
        .package(url: "https://github.com/sqlcipher/SQLCipher.swift.git", from: "4.10.0")
    ],
    targets: [
        .target(
            name: "DbPlugin",
            dependencies: [
                .product(name: "Capacitor", package: "capacitor-swift-pm"),
                .product(name: "Cordova", package: "capacitor-swift-pm"),
                .product(
                    name: "SQLCipher",
                    package: "SQLCipher.swift",
                    condition: .when(traits: ["SQLCipher"])
                )
            ],
            path: "ios/Sources/DbPlugin"
        )
    ],
    swiftLanguageModes: [.v5]
)

Überprüfen Sie das SDK-Plugin in seinem eigenen Repository, um die aktuelle Paket-URL, Produktname und Version zu überprüfen, bevor Sie diese kopieren.

Punkte, die leicht übersehen werden:

  • Tools-Version 6.x ändert die Standard-Sprachmodus auf Swift 6 für Ihre Ziele. Capacitor unterstützt Swift 6 noch nicht offiziell, daher sollten Sie swiftLanguageModes: [.v5] nicht verwenden, bis Ihr code für strikte Konkurrenz bereit ist.
  • Durch Erhöhung der Version Ihres Plugins auf 6.1 müssen die Konsumenten Xcode 16.3+ verwenden. Capacitor 8 Apps erfordern bereits Xcode 26, also ist das keine neue Einschränkung.

Verwenden Sie den Merkmal in code

Aktivierte Merkmale sind Kompilierungsbedingungen in den Zielen Ihres Pakets:

#if SQLCipher
import SQLCipher
#endif

@objc func open(_ call: CAPPluginCall) {
    let key = call.getString("encryptionKey")
    #if SQLCipher
    // open with key
    #else
    if key != nil {
        call.unavailable("Encryption requires the SQLCipher trait. Enable it in experimental.ios.spm.packageTraits.")
        return
    }
    #endif
    // open without encryption
}

Geben Sie eine klare Fehlermeldung mit dem Namen des Merkmals zurück, wenn eine Funktion ausgeschaltet ist. Ansonsten sehen App-Entwickler eine stille Fehlfunktion und beschuldigen das Plugin.

Sie können auch Ihren eigenen Flag mit swiftSettings: [.define("ACME_SQLCIPHER", .when(traits: ["SQLCipher"]))] Entwerfen Sie Merkmale als additiv

Designmerkmale additiv zu sein

SwiftPM vereint Merkmale über die Abhängigkeitsgraphik hinweg. Wenn zwei Pakete auf Ihr Plugin mit unterschiedlichen Merkmalen abhängig sind, ist die Vereinigung aktiviert. Also:

  • Ermöglichung einer Eigenschaft sollte Fähigkeiten hinzufügen, nicht entfernen oder API ändern.
  • Vermeide gegensätzliche Merkmale. Wenn du nicht kannst, versage den Build.
#if TraitA && TraitB
#error("TraitA and TraitB cannot be enabled together")
#endif

Testen Sie jede Combination

swift build On eigener Rechnung baut es für den Mac, und ein Plugin, das nur auf Capacitor angewiesen ist, baut nur für iOS, also testen Sie die Merkmale über eine Capacitor Testanwendung, die für einen iOS Simulator erstellt wurde. Für jede Combination (keine Einträge für die Standardmerkmale, usw.), ändern Sie ['SQLCipher'], ['.defaults', 'SQLCipher'] und so weiter packageTraits in der Konfiguration der Test-App, dann synchronisieren und bauen:

bunx cap sync ios
xcodebuild build \
  -project ios/App/App.xcodeproj \
  -scheme App \
  -destination 'generic/platform=iOS Simulator' \
  CODE_SIGNING_ALLOWED=NO

Hinzufügen jeder Combination als eigenes Job zur CI.

Behalten Sie CocoaPods-Nutzer im Auge

Merkmal existieren nur in SPM. Wenn Ihr Plugin auch eine podspec bereitstellt, bieten Sie die gleiche Wahl wie Subspezifikationen:

s.default_subspec = 'Core'

s.subspec 'Core' do |core|
  core.source_files = 'ios/Sources/DbPlugin/**/*.swift'
  core.dependency 'Capacitor'
end

s.subspec 'SQLCipher' do |sc|
  sc.dependency 'AcmeCapacitorDb/Core'
  sc.dependency 'SQLCipher', '~> 4.10'
  sc.pod_target_xcconfig = { 'SWIFT_ACTIVE_COMPILATION_CONDITIONS' => '$(inherited) SQLCipher' }
end

Die Festlegung des gleichen Kompilationsbedingungsnamens in der Subspezifikation ermöglicht Ihnen, einen #if SQLCipher code Weg. CocoaPods-Anwendungen wählen dann die Subspezifikation in ihrem Podfile aus. Die Capacitor CLI schreibt eine pod Zeile pro Plugin innerhalb capacitor_pods, so fügen Sie die zusätzliche Zeile in Ihrem README ein. Wie man CocoaPods mit Capacitor 8 verwendet zeigt, wo benutzerdefinierte Pod-Linien hingehen.

Beschränkungen

  • Experimental. Die Optionen befinden sich unter experimental und kann sich dann weiterentwickeln ios.spm.* in einer zukünftigen Hauptversion. Eine Konfigurationsumbenennung ist zu erwarten.
  • Swift 6 wird offiziell nicht unterstützt. The CLI’s own docs warn that setting swiftToolsVersion zu Versionen 6.0 oder höher können Probleme auftreten. Testen Sie die vollständige App, insbesondere Plugins, die binäre xcframeworks liefern.
  • Nur für iOS. Android hat in Capacitor keine Entsprechung. Plugins verwalten optionalen Android-SDKs mit Gradle-Variablen in variables.gradle Plugins müssen sich anmelden.
  • Plugins müssen sich anmelden. Die meisten Plugins definieren noch keine Merkmale. Überprüfen Sie dies, bevor Sie eines planen.

Troubleshooting

Die Synchronisierung fehlt mit der Meldung „Merkmalpakete erfordern eine explizite Swift-Tools-Version von 6.1 oder höher“. Hinzufügen swiftToolsVersion: '6.1' nächstens packageTraits.

SwiftPM meldet ein unbekanntes Merkmal. Merkmalnamen sind case-sensitive und müssen im Plugin vorhanden sein. Package.swift Für die installierte Version.

Die Funktion fehlt auch nach Aktivierung des Merkmals. Räumen Sie den Package-Caches in Xcode, löschen Sie den Build-Ordner und bestätigen Sie die generierte CapApp-SPM/Package.swift hat das traits: Suffix. Die Bearbeitung dieses Dateis durch Handänderung bleibt nicht bestehen, da CLI es auf jeder Synchronisierung neu schreibt.

Fehler in Swift code nach Erhöhung der Werkzeugversion. Das ist die Swift 6-Sprachmodus in einem Paket, das du kontrollierst. Füge swiftLanguageModes: [.v5].

Konflikte zwischen Plugins. Da CLI 8.4, experimental.ios.spm.packageOptions lässt dich das symlink oder moduleAliases mehr pro Plugin. Weitere Informationen dazu finden Sie in der Capacitor iOS troubleshooting guide.

pro Plugin. Mehr dazu in der Capacitor iOS-FehlersucheWenn Sie Cloud-Builds möchten, die bereits aktuelles Xcode für SPM-Projekte ausführen, sehen Sie sich Capgo Build.

Live Updates für Capacitor-Apps

Wenn ein Bug im Weblayer lebt, schicken Sie die Reparatur über Capgo anstatt Tage zu warten, bis die App im App Store genehmigt ist. Die Benutzer erhalten die Aktualisierung im Hintergrund, während native Änderungen im normalen Review-Verfahren bleiben.

Menschliche Unterstützung von Martin

Los geht's jetzt

Neueste von unserem Blog

Capgo gibt Ihnen die besten Einblicke, die Sie benötigen, um eine wirklich professionelle mobile App zu erstellen.