Saltare al contenuto principale

How to Use SPM Package Traits in Capacitor 8

Usa le caratteristiche dei pacchetti SPM in Capacitor 8: abilita le funzionalità dei plugin facoltative con packageTraits, impostare swiftToolsVersion a 6.1 e aggiungi caratteristiche al tuo proprio plugin.

Martin Donadieu

Martin Donadieu

Writer

Valeria

Recensore

Jordan

Editore

How to Use SPM Package Traits in Capacitor 8

To use SPM package traits in Capacitor 8, set experimental.ios.spm.swiftToolsVersion a "6.1" e elencare le caratteristiche per plugin sotto experimental.ios.spm.packageTraits in il tuo config Capacitor, quindi esegui bunx cap sync ios. Il CLI scrive quelle caratteristiche nella generata CapApp-SPM/Package.swift, e SwiftPM costruisce il plugin con le dipendenze native facoltative e i percorsi di code che corrispondono. Ciò richiede Capacitor CLI 8.3.0 o successivo e si applica solo ai progetti iOS che utilizzano il gestore di pacchetti Swift.

Le caratteristiche chiudono l'ultima grande lacuna tra SPM e CocoaPods per i plugin: dipendenze native facoltative che un tempo erano subspec di podspec. Questa guida copre il lato dell'app, il lato dell'autore del plugin e i limiti dell'attuale supporto sperimentale.

Quali sono le caratteristiche dei pacchetti

Package traits come from Swift Evolution proposal SE-0450, implementata in Swift 6.1 (Xcode 16.3 e successive versioni). Un pacchetto dichiara caratteristiche denominate nel suo Package.swift. I consumatori scelgono quali attivare quando dipendono dal pacchetto. Una caratteristica può:

  • rendere una dipendenza facoltativa (condition: .when(traits: [...]) su una dipendenza di destinazione)
  • abilitare i percorsi code, poiché ogni tratto abilitato è disponibile come condizione di compilazione.#if TraitName),
  • toggle build settings such as defines or linker flags,
  • abilitare altre caratteristiche.

Un pacchetto può anche segnalare i tratti come predefiniti. Sono attivi a meno che il consumatore non passi una lista esplicita.

Se conosci le subspecs di CocoaPods o le feature di Cargo in Rust, è la stessa idea.

Why matters in Capacitor

Capacitor genera l'applicazione Package.swift for you, so you can’t hand-edit dependency lines to pass traits. Before CLI 8.3, plugin authors with an optional native SDK had two bad choices on SPM: always link the SDK, increasing size and sometimes adding privacy or export compliance work, or publish a second plugin. Caso comuni:

  • crittografati vs SQLite puro (SQLCipher),
  • SDK di analytics con e senza raccolta dell'identificatore di pubblicità
  • un SDK di vendor facoltativo per un provider di pagamento o di accesso
  • strumenti di debug esclusivamente.

Abilita le caratteristiche in tuo app

1. Controlla le versioni

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

La progetto deve utilizzare SPM: ios/App/CapApp-SPM esiste. Se sei su CocoaPods, vedi come migrare il tuo Capacitor app a SPM.

2. Trova i nomi dei tratti del plugin

Apre il plugin's Package.swift in node_modules e cerca l'array, o controlla il suo README. I nomi dei tratti sono case-sensitive. traits: array, o consulta il suo README. I nomi dei tratti sono case-sensitive.

3. Configura 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 chiave è il nome del pacchetto del plugin npm. Il valore è l'elenco delle caratteristiche da abilitare.

4. Sincronizza e controlla l'output

bunx cap sync ios

La generata ios/App/CapApp-SPM/Package.swift ora inizia con // swift-tools-version: 6.1 e la riga di dipendenza del plugin porta i tratti:

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

Il CLI scrive .defaults (o defaults, .default, default in ogni caso) come il valore SwiftPM .defaults e ogni altro nome come una stringa a citazione.

Costruisci in Xcode. Se Xcode mostra ancora la vecchia grafica, utilizza File > Pacchetti > Reset Pacchetti Caching.

Regola che il CLI applica

Il Capacitor CLI verifica la configurazione durante la sincronizzazione:

  • Se qualsiasi plugin ha una lista di caratteristiche non vuota e swiftToolsVersion Mancanza di versione Swift esplicita per gli strumenti 6.1 o superiore impedisce la sincronizzazione.
  • Se swiftToolsVersion è inferiore a 6.1, la sincronizzazione si ferma e ti dice che la versione è troppo bassa.
  • swiftToolsVersion deve avere l'aspetto 6.1 o 6.1.0.
  • Non vengono trattati come se non fossero elencati gli array vuoti.

Tenere o abbandonare le caratteristiche predefinite

Elenco caratteristiche sostituisce i valori predefiniti. Confronta:

Valore di configurazione Risultato
non elencato caratteristiche predefinite del plugin
['SQLCipher'] solamente SQLCipher, default disattivati
['.defaults', 'SQLCipher'] predefiniti più SQLCipher

Leggi i documenti del plugin prima di resettare i valori predefiniti. Un plugin potrebbe mettere il backend standard dietro un tratto predefinito.

Aggiungi caratteristiche al tuo proprio plugin

Se mantieni un plugin con un opzionale SDK, ecco un esempio completo Package.swiftLa denominazione del pacchetto deve corrispondere al nome che Capacitor CLI deriva dal tuo npm nome (@acme/capacitor-db diventa AcmeCapacitorDbvedi migrare un plugin Capacitor a SPM per la regola.

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

Controlla il repository del SDK per il suo URL del pacchetto, il nome del prodotto e la versione prima di copiare questo.

Punti che sono facili da trascurare:

  • Le versioni degli strumenti 6.x modificano il modello di lingua predefinito a Swift 6 Capacitor non supporta ufficialmente Swift 6 ancora, quindi mantieni swiftLanguageModes: [.v5] se il tuo code non è pronto per la concorrenza stretta.
  • Aumentando la versione degli strumenti del tuo plugin a 6.1, i consumatori richiedono Xcode 16.3+. Capacitor 8 app già richiedono Xcode 26, quindi non è una nuova restrizione.

Utilizza il trait in code

Il trait abilitato sono condizioni di compilazione nei target del tuo pacchetto:

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

Restituisci un errore chiaro che nomina il trait quando una funzionalità è disabilitata. Gli sviluppatori di app altrimenti vedono un fallimento silenzioso e incolpano il plugin.

Potresti anche definire il tuo proprio flag con swiftSettings: [.define("ACME_SQLCIPHER", .when(traits: ["SQLCipher"]))] se preferisci un nome prefisso.

Progetta i trait per essere aggiuntivi

SwiftPM unifica i trait all'interno della graffica di dipendenza. Se due pacchetti dipendono dal tuo plugin con diversi trait, l'unione è abilitata. Quindi:

  • Abilitare un trait dovrebbe aggiungere capacità, non rimuovere API o modificare i valori predefiniti.
  • Evita le caratteristiche esclusive tra loro. Se non puoi, falla costruire con un errore evidente.
#if TraitA && TraitB
#error("TraitA and TraitB cannot be enabled together")
#endif

Testa ogni combinazione

swift build On Mac, il costruisce da solo, e un plugin che dipende solo da Capacitor costruisce solo per iOS, quindi testa le caratteristiche attraverso un'app di test Capacitor costruita per un simulatore iOS. Per ogni combinazione (nessuna voce per le caratteristiche predefinite, ['SQLCipher'], ['.defaults', 'SQLCipher'] E via di questo passo packageTraits Nella configurazione dell'app di test, sincronizza e costruisci:

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

Aggiungi ogni combinazione al CI come lavoro separato.

Tieni coperti gli utenti di CocoaPods

Le caratteristiche esistono solo in SPM. Se il tuo plugin invia anche un podspec, offri la stessa scelta come sottospecie:

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

Impostando lo stesso nome di condizione di compilazione nella subspec ti consente di condividere #if SQLCipher code path. CocoaPods apps then select the subspec in their Podfile. The Capacitor CLI writes one pod Come utilizzare CocoaPods con __CAPGO_KEEP_0__ 8 capacitor_podsmostra dove vanno le righe di pod personalizzate. Come utilizzare CocoaPods con Capacitor 8 mostra dove vanno le righe di pod personalizzate.

Limitazioni

  • Experimentale. Ille opzioni sono disponibili sotto experimental e possono essere spostate in ios.spm.* in a future major. Expect a config rename at some point.
  • Non supportato ufficialmente da Swift 6. Il CLI stesso avverte che impostare swiftToolsVersion a 6.0 o superiore può causare problemi. Testare l'app completa, soprattutto i plugin che distribuiscono xcframeworks binari.
  • Solo per iOS. Android non ha un equivalente in Capacitor. I plugin gestiscono gli SDK Android facoltativi tramite variabili Gradle in variables.gradle o artefatti separati.
  • I plugin devono optare per l'opzione. Most plugins don’t define traits yet. Check before you plan on one.

Troubleshooting

La sincronizzazione fallisce con “I tratti del pacchetto richiedono una versione esplicita degli strumenti Swift di 6.1 o superiore”. Aggiungi swiftToolsVersion: '6.1' accanto a packageTraits.

SwiftPM segnala un tratto sconosciuto. Il nome dei tratti è case-sensitive e deve esistere nel plugin. Package.swift per la versione installata.

Caratteristica ancora mancante dopo l'abilitazione del tratto. La caratteristica mancante non è ancora presente dopo aver abilitato il trait. CapApp-SPM/Package.swift ha traits: ha il suffisso. La modifica di quel file a mano non tiene, poiché il CLI lo riscrive ogni volta che sincronizza.

Errori in Swift code dopo l'aumento della versione degli strumenti. Quella è la modalità linguistica Swift 6 in un pacchetto che controlli. Aggiungi swiftLanguageModes: [.v5].

Conflitti di nome tra plugin. Dal CLI 8.4, experimental.ios.spm.packageOptions ti consente di impostare symlink o moduleAliases per plugin. Ulteriori informazioni su ciò in Capacitor iOS troubleshooting guide.

Per la visione più ampia del pacchetto SPM, leggere SPM vs CocoaPods per CapacitorSe desideri costruire in cloud con Xcode corrente già eseguito per i progetti SPM, vedi Capgo Build.

Aggiornamenti in tempo reale per le app Capacitor

Quando un bug del layer web è attivo, invia la correzione attraverso Capgo invece di attendere giorni per l'approvazione della store. Gli utenti ricevono l'aggiornamento in background mentre le modifiche native rimangono nel normale percorso di revisione.

Ultimi articoli dal nostro Blog

Capgo vi dà le migliori informazioni che avete bisogno per creare un'app mobile veramente professionale.