Passer à la navigation principale

Comment utiliser les traits de package SPM dans Capacitor 8

Utilisez les traits de package SPM dans Capacitor 8 : activez les fonctionnalités du plugin facultatives avec packageTraits, définissez swiftToolsVersion 6.1 et ajoutez des traits à votre propre plugin.

Martin Donadieu

Martin Donadieu

Writer

Valeria

Réviseur

Jordan

Éditeur

Comment utiliser les traits de package SPM dans Capacitor 8

To use SPM package traits in Capacitor 8, set experimental.ios.spm.swiftToolsVersion à "6.1" et lister les traits par plugin sous experimental.ios.spm.packageTraits dans votre configuration Capacitor, puis exécutez bunx cap sync iosLe CLI écrit ces traits dans le code généré. CapApp-SPM/Package.swift, et SwiftPM construit le plugin avec les dépendances optionnelles correspondantes et les chemins code. Cela nécessite Capacitor CLI 8.3.0 ou ultérieur et ne s'applique qu'aux projets iOS utilisant le gestionnaire de packages Swift.

Les traits ferment le dernier grand écart entre SPM et CocoaPods pour les plugins : les dépendances natives optionnelles qui étaient auparavant des sous-espèces de podspec. Ce guide couvre le côté de l'application, le côté de l'auteur de plugin et les limites de la prise en charge expérimentale actuelle.

Quels sont les traits de package ?

Les traits de package proviennent de la proposition d'évolution Swift. SE-0450, mis en œuvre dans Swift 6.1 (Xcode 16.3 et ultérieur). Un package déclare des traits nommés dans son Package.swiftLes consommateurs choisissent lesquels activer lorsqu'ils dépendent du package. Un trait peut :

  • rendre une dépendance optionnelle (condition: .when(traits: [...]) sur une dépendance cible)
  • activer les chemins code , puisque chaque trait activé est disponible en tant que condition de compilation (#if TraitName),
  • toggle build settings such as defines or linker flags,
  • activer d'autres traits.

Un package peut également marquer des traits par défaut. Ils sont activés sauf si le consommateur passe une liste explicite.

Si vous connaissez les subspecs de CocoaPods ou les fonctionnalités de Cargo en Rust, c'est la même idée.

Why cela compte dans Capacitor

Capacitor génère l'application's Package.swift pour vous, afin que vous ne puissiez pas modifier manuellement les lignes de dépendance pour activer les traits. Avant CLI 8.3, les auteurs de plugins avec un SDK natif facultatif avaient deux mauvaises choix sur SPM : toujours lier le SDK, augmentant la taille et parfois ajoutant du travail de conformité à la vie privée ou d'exportation, ou publier un deuxième plugin. Cas courants :

  • chiffrement vs SQLite non chiffré (SQLCipher),
  • SDK d'analytique avec et sans collecte de l'identifiant de l'annonceur,
  • un SDK de fournisseur facultatif pour un fournisseur de paiement ou de connexion,
  • outillage de débogage uniquement.

Activer les traits dans votre application

1. Vérifiez les versions

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

Le projet doit utiliser SPM : ios/App/CapApp-SPM existe. Si vous utilisez CocoaPods, voir comment migrer votre application Capacitor vers SPM.

2. Trouvez les noms de traits du plugin

Ouvrez le plugin's Package.swift en node_modules et recherchez la traits: array ou consultez son fichier README. Les noms de traits sont sensibles à la casse.

3. Configurez 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;

La clé est le nom de package du plugin npm. La valeur est la liste des traits à activer.

4. Synchronisez et vérifiez le résultat

bunx cap sync ios

Le fichier généré ios/App/CapApp-SPM/Package.swift commence désormais par // swift-tools-version: 6.1 et la ligne de dépendance du plugin porte les traits :

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

Le CLI écrit .defaults (ou defaults, .default, default en tout cas) comme la valeur SwiftPM .defaults et chaque autre nom sous forme de chaîne de caractères.

Construire dans Xcode. Si Xcode affiche toujours l'ancien graphique, utilisez Fichier > Packages > Réinitialiser les caches de packages.

Les règles que CLI applique

Le Capacitor CLI valide la configuration lors de la synchronisation :

  • Si tout plugin possède une liste de traits non vide et swiftToolsVersion La synchronisation s'arrête car « les traits de package nécessitent une version explicite de Swift tools de 6.1 ou supérieure ».
  • Si swiftToolsVersion est inférieur à 6.1, la synchronisation s'arrête et vous informe que la version est trop basse.
  • swiftToolsVersion doit ressembler à 6.1 ou 6.1.0.
  • Plugins avec un tableau vide sont traités comme s'ils n'étaient pas listés.

Conservation ou suppression des valeurs par défaut

Lister les traits remplace les valeurs par défaut. Comparez :

Valeur de configuration Résultat
non listé traits par défaut du plugin
['SQLCipher'] seulement SQLCipher, valeurs par défaut désactivées
['.defaults', 'SQLCipher'] valeur par défaut plus SQLCipher

Lisez les documents du plugin avant de supprimer les valeurs par défaut. Un plugin peut mettre son backend standard derrière un trait par défaut.

Ajoutez des traits à votre propre plugin

Si vous gérez un plugin avec un SDK facultatif, voici un exemple complet Package.swiftLe nom du package doit correspondre au nom que le Capacitor CLI dérive de votre nom de npm (@acme/capacitor-db devient AcmeCapacitorDbVoir migrer un plugin Capacitor vers SPM pour la règle.

// 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]
)

Vérifiez le repository du SDK pour son URL de package, son nom de produit et sa version avant de copier cela.

Points faciles à manquer :

  • Les outils version 6.x changent le mode de langue par défaut en Swift 6 Le Capacitor n'est pas officiellement compatible avec Swift 6, donc gardez swiftLanguageModes: [.v5] sauf si votre code est prêt pour la concurrence stricte.
  • Raising your plugin’s tools version to 6.1 means consumers need Xcode 16.3+. Capacitor 8 applications nécessitent déjà Xcode 26, ce qui n'est donc pas une nouvelle contrainte.

Utilisez le trait dans code

Les traits activés sont des conditions de compilation dans vos cibles de package :

#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
}

Retournez une erreur claire en nommant le trait lorsque une fonctionnalité est désactivée. Les développeurs d'applications ne verront pas d'échec silencieux et blâmeront le plugin.

Vous pouvez également définir votre propre drapeau avec swiftSettings: [.define("ACME_SQLCIPHER", .when(traits: ["SQLCipher"]))] si vous préférez un nom préfixé.

Concevez les traits pour qu'ils soient additives

SwiftPM unifie les traits à travers le graphique de dépendances. Si deux packages dépendent de votre plugin avec différents traits, l'union est activée. Ainsi :

  • Activer un trait devrait ajouter des capacités, pas supprimer API ou modifier les valeurs par défaut.
  • Avoid mutually exclusive traits. If you can’t, fail the build loudly:
#if TraitA && TraitB
#error("TraitA and TraitB cannot be enabled together")
#endif

Testez toutes les combinaisons

swift build On macOS, il construit seul, tandis qu'un plugin qui dépend uniquement de Capacitor ne construit que pour iOS, testez donc les traits à travers une application de test Capacitor construite pour un simulateur iOS. Pour chaque combinaison (pas d'entrée pour les traits par défaut, et ainsi de suite), modifiez ['SQLCipher'], ['.defaults', 'SQLCipher'] et ainsi de suite), modifier packageTraits in the test app’s config, then sync and build:

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

Ajoutez chaque combinaison à CI comme job distinct.

Prenez en charge les utilisateurs de CocoaPods.

Les traits n'existent que dans SPM. Si votre plugin fournit également un podspec, proposez le même choix que les sous-espèces :

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

Définir le même nom de condition de compilation dans la sous-spec permet de partager un #if SQLCipher Le chemin de code. Les applications CocoaPods sélectionnent ensuite la sous-édition dans leur fichier Podfile. Le Capacitor CLI écrit une seule pod Comment utiliser CocoaPods avec __CAPGO_KEEP_0__ 8 capacitor_podsmontre où vont les lignes de pod personnalisées. Comment utiliser CocoaPods avec Capacitor 8 montre où les lignes de pod personnalisées s'insèrent.

Limitations

  • Expérimental. Les options se trouvent sous experimental et peuvent être déplacées vers ios.spm.* Dans une future majeure. Attendez une renommage de la config à un moment donné.
  • Swift 6 non officiellement pris en charge. Les documents de CLI avertissent que la mise en place swiftToolsVersion to 6.0 or higher may cause issues. Test the full app, especially plugins that ship binary xcframeworks.
  • iOS only. Android n'a pas d'équivalent en Capacitor. Les plugins gèrent les SDK Android optionnels avec des variables Gradle en variables.gradle Les plugins doivent s'abonner.
  • Les plugins doivent s'inscrire. La plupart des plugins n'ont pas encore défini de traits. Vérifiez avant de planifier un.

Troubleshooting

La synchronisation échoue avec « Les traits de package nécessitent une version explicite de Swift tools de 6.1 ou supérieure ». Ajouter swiftToolsVersion: '6.1' à côté de packageTraits.

SwiftPM signale un trait inconnu. Les noms de traits sont sensibles à la casse et doivent exister dans le plugin. Package.swift pour la version installée.

La fonctionnalité manque toujours après avoir activé le trait. Réinitialisez les caches de packages dans Xcode, nettoyez le dossier de build et confirmez la génération. CapApp-SPM/Package.swift possède le traits: suffixe. L'édition de ce fichier à la main ne tient pas, puisque CLI le reécrit à chaque synchronisation.

Erreurs en Swift code après avoir augmenté la version des outils. C'est le mode de langage Swift 6 dans un package que vous contrôlez. Ajoutez swiftLanguageModes: [.v5].

Conflits de noms entre plugins. Depuis CLI 8.4, experimental.ios.spm.packageOptions vous pouvez définir symlink ou moduleAliases par plugin. En savoir plus à ce sujet. Capacitor iOS troubleshooting guide.

__CAPGO_KEEP_0__ guide de dépannage iOS SPM vs CocoaPods pour CapacitorSi vous souhaitez des builds cloud qui exécutent déjà la version actuelle d'Xcode pour les projets SPM, consultez Capgo Construction.

Mises à jour instantanées pour les applications Capacitor

Lorsqu'un bug de la couche web est en ligne, expédiez la correction par Capgo au lieu d'attendre des jours pour l'approbation de la boutique d'applications. Les utilisateurs reçoivent la mise à jour en arrière-plan tandis que les modifications natives restent dans la voie de revue normale.

un soutien humain de Martin

Démarrer maintenant

Dernières actualités de notre Blog

Capgo vous offre les meilleures informations nécessaires pour créer une application mobile véritablement professionnelle.