Skip to content

feat: add experimental Swift Package Manager (SPM) support#330

Open
robingenz wants to merge 4 commits intomainfrom
feat/add-spm-support
Open

feat: add experimental Swift Package Manager (SPM) support#330
robingenz wants to merge 4 commits intomainfrom
feat/add-spm-support

Conversation

@robingenz
Copy link
Copy Markdown
Member

Summary

Adds Swift Package Manager (SPM) support to all seven iOS-enabled plugins: barcode-scanning, document-scanner, face-detection, face-mesh-detection, selfie-segmentation, subject-segmentation, and translation.

Changes

  • New Package.swift manifest for each plugin (iOS 15, Swift 5.9, Capacitor 8+).
  • ML Kit dependencies are resolved via d-date/google-mlkit-swiftpm, since Google does not officially ship ML Kit via SPM. Version pinned via .upToNextMinor(from: "8.0.0") to match the existing ~> 8.0.0 CocoaPods constraint.
  • Migrated each plugin class from the Objective-C bridge macros (CAP_PLUGIN / CAP_PLUGIN_METHOD) to the Swift CAPBridgedPlugin protocol. Added identifier, jsName, and pluginMethods properties listing every exposed method.
  • Removed the now-obsolete *.h / *.m bridge files and cleaned their entries from each Xcode project.pbxproj.
  • Added SPM-related entries (Package.resolved, /.build, /Packages, .swiftpm/..., .netrc) to each plugin's .gitignore.
  • Added Package.swift to each plugin's files array in package.json and a new ios:spm:install script.
  • Removed the top-level README warning stating SPM is not supported.

Note: the language-identification package has no iOS implementation, so it is unaffected.

Test plan

  • npm run verify:ios for each plugin continues to succeed via CocoaPods
  • In a sample app, add each plugin via SPM (https://github.com/capawesome-team/capacitor-mlkit.git) and confirm the library product resolves and the build succeeds
  • On iOS device/simulator, run the plugins' public API (e.g. barcode scan, translate) and verify behavior matches the CocoaPods build
  • Verify ML Kit version parity between the d-date SPM package and the podspec's GoogleMLKit/* ~> 8.0.0

Copilot AI review requested due to automatic review settings April 17, 2026 05:45
@robingenz robingenz changed the title feat: add Swift Package Manager (SPM) support feat: add experimental Swift Package Manager (SPM) support Apr 17, 2026
@robingenz robingenz self-assigned this Apr 17, 2026
@robingenz robingenz added the feature Feature label Apr 17, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Swift Package Manager (SPM) support across the iOS-enabled plugins by introducing per-plugin Package.swift manifests and migrating Capacitor iOS plugins to the Swift CAPBridgedPlugin registration style.

Changes:

  • Add Package.swift for each plugin and wire in Capacitor + (where needed) ML Kit SPM dependencies.
  • Migrate iOS plugin registration from CAP_PLUGIN Objective-C bridge files to CAPBridgedPlugin (identifier, jsName, pluginMethods) and remove obsolete .h/.m files + Xcode project references.
  • Add Turbo/CI scripts for SPM dependency resolution and update plugin packaging/gitignore rules to include SPM artifacts.

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
turbo.json Adds a new Turbo task (ios:spm:install) to support SPM dependency resolution.
package.json Adds root scripts to run SPM install tasks (including affected/all variants) via Turbo.
README.md Removes the top-level warning claiming SPM is not supported.
.github/workflows/ci.yml Adds CI steps to resolve SPM dependencies and tweaks Turbo SCM base configuration.
packages/barcode-scanning/package.json Publishes Package.swift and adds an ios:spm:install script.
packages/barcode-scanning/ios/Plugin/BarcodeScannerPlugin.swift Migrates plugin registration to CAPBridgedPlugin and lists exposed methods.
packages/barcode-scanning/ios/Plugin/BarcodeScannerPlugin.m Removes Objective-C bridge macro registration file.
packages/barcode-scanning/ios/Plugin/BarcodeScannerPlugin.h Removes obsolete public header.
packages/barcode-scanning/ios/Plugin.xcodeproj/project.pbxproj Cleans removed .h/.m references from the Xcode project.
packages/barcode-scanning/Package.swift Adds SPM manifest for the barcode scanning plugin (Capacitor + MLKit).
packages/barcode-scanning/.gitignore Ignores common SPM-generated files/directories.
packages/document-scanner/package.json Publishes Package.swift and adds an ios:spm:install script.
packages/document-scanner/Package.swift Adds SPM manifest for the document scanner plugin.
packages/face-detection/package.json Publishes Package.swift and adds an ios:spm:install script.
packages/face-detection/ios/Plugin/FaceDetectionPlugin.swift Migrates plugin registration to CAPBridgedPlugin and lists exposed methods.
packages/face-detection/ios/Plugin/FaceDetectionPlugin.m Removes Objective-C bridge macro registration file.
packages/face-detection/ios/Plugin/FaceDetectionPlugin.h Removes obsolete public header.
packages/face-detection/ios/Plugin.xcodeproj/project.pbxproj Cleans removed .h/.m references from the Xcode project.
packages/face-detection/Package.swift Adds SPM manifest for the face detection plugin (Capacitor + MLKit).
packages/face-detection/.gitignore Ignores common SPM-generated files/directories.
packages/face-mesh-detection/package.json Publishes Package.swift and adds an ios:spm:install script.
packages/face-mesh-detection/ios/Plugin/FaceMeshDetectionPlugin.swift Migrates plugin registration to CAPBridgedPlugin and lists exposed methods.
packages/face-mesh-detection/ios/Plugin/FaceMeshDetectionPlugin.m Removes Objective-C bridge macro registration file.
packages/face-mesh-detection/ios/Plugin/FaceMeshDetectionPlugin.h Removes obsolete public header.
packages/face-mesh-detection/ios/Plugin.xcodeproj/project.pbxproj Cleans removed .h/.m references from the Xcode project.
packages/face-mesh-detection/Package.swift Adds SPM manifest for the face mesh detection plugin.
packages/face-mesh-detection/.gitignore Ignores common SPM-generated files/directories.
packages/selfie-segmentation/package.json Publishes Package.swift and adds an ios:spm:install script.
packages/selfie-segmentation/ios/Plugin/SelfieSegmentationPlugin.swift Migrates plugin registration to CAPBridgedPlugin and lists exposed methods.
packages/selfie-segmentation/ios/Plugin/SelfieSegmentationPlugin.m Removes Objective-C bridge macro registration file.
packages/selfie-segmentation/ios/Plugin/SelfieSegmentationPlugin.h Removes obsolete public header.
packages/selfie-segmentation/ios/Plugin.xcodeproj/project.pbxproj Cleans removed .h/.m references from the Xcode project.
packages/selfie-segmentation/Package.swift Adds SPM manifest for the selfie segmentation plugin (Capacitor + MLKit).
packages/selfie-segmentation/.gitignore Ignores common SPM-generated files/directories.
packages/subject-segmentation/package.json Publishes Package.swift and adds an ios:spm:install script.
packages/subject-segmentation/ios/Plugin/SubjectSegmentationPlugin.swift Migrates plugin registration to CAPBridgedPlugin and lists exposed methods.
packages/subject-segmentation/ios/Plugin/SubjectSegmentationPlugin.m Removes Objective-C bridge macro registration file.
packages/subject-segmentation/Package.swift Adds SPM manifest for the subject segmentation plugin.
packages/translation/package.json Publishes Package.swift and adds an ios:spm:install script.
packages/translation/ios/Plugin/TranslationPlugin.swift Migrates plugin registration to CAPBridgedPlugin and lists exposed methods.
packages/translation/ios/Plugin/TranslationPlugin.m Removes Objective-C bridge macro registration file.
packages/translation/ios/Plugin/TranslationPlugin.h Removes obsolete public header.
packages/translation/ios/Plugin.xcodeproj/project.pbxproj Cleans removed .h/.m references from the Xcode project.
packages/translation/Package.swift Adds SPM manifest for the translation plugin (Capacitor + MLKit).
packages/translation/.gitignore Ignores common SPM-generated files/directories.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/subject-segmentation/package.json
Comment thread .github/workflows/ci.yml
Comment thread packages/translation/package.json
Comment thread packages/barcode-scanning/package.json
Comment thread packages/document-scanner/package.json
Comment thread packages/face-detection/package.json
Comment thread packages/face-mesh-detection/package.json
Comment thread packages/selfie-segmentation/package.json
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 17, 2026

Open in StackBlitz

@capacitor-mlkit/barcode-scanning

npm i https://pkg.pr.new/capawesome-team/capacitor-mlkit/@capacitor-mlkit/barcode-scanning@330

@capacitor-mlkit/document-scanner

npm i https://pkg.pr.new/capawesome-team/capacitor-mlkit/@capacitor-mlkit/document-scanner@330

@capacitor-mlkit/face-detection

npm i https://pkg.pr.new/capawesome-team/capacitor-mlkit/@capacitor-mlkit/face-detection@330

@capacitor-mlkit/face-mesh-detection

npm i https://pkg.pr.new/capawesome-team/capacitor-mlkit/@capacitor-mlkit/face-mesh-detection@330

@capacitor-mlkit/selfie-segmentation

npm i https://pkg.pr.new/capawesome-team/capacitor-mlkit/@capacitor-mlkit/selfie-segmentation@330

@capacitor-mlkit/subject-segmentation

npm i https://pkg.pr.new/capawesome-team/capacitor-mlkit/@capacitor-mlkit/subject-segmentation@330

@capacitor-mlkit/translation

npm i https://pkg.pr.new/capawesome-team/capacitor-mlkit/@capacitor-mlkit/translation@330

commit: 31d9b93

@jacobg
Copy link
Copy Markdown

jacobg commented Apr 17, 2026

@robingenz Thanks. I'm getting Xcode build error resolving package versions after installing this plugin.

@robingenz
Copy link
Copy Markdown
Member Author

@jacobg Would you be willing to debug it and create a PR based on this branch?

@jacobg
Copy link
Copy Markdown

jacobg commented Apr 17, 2026

@robingenz I started to look at it. I tried Android first, since this PR shouldn't affect that, and I'm getting build error:

package com.google.common.util.concurrent does not exist

BarcodeScanner.java imports ListenableFuture in that package. That package is guava, and I'm not sure how it would ever work since guava is not listed as a maven dependency.

Can you please clarify that? Thanks.

@robingenz
Copy link
Copy Markdown
Member Author

@jacobg Nothing has changed for Android (feel free to check out the changes in this PR). This must be a local configuration issue.

@jacobg
Copy link
Copy Markdown

jacobg commented Apr 19, 2026

@jacobg Nothing has changed for Android (feel free to check out the changes in this PR). This must be a local configuration issue.

@robingenz It was because I was overriding to use camerax 1.6.0 whereas capacitor-mlkit by default using 1.5.2. It seems 1.5.2 exposed com.google.common.util.concurrent.ListenableFuture that you can import, whereas 1.6.0 no longer does. If capacitor-mlkit is directly using ListenableFuture shouldn't it declare it as a dependency?

@robingenz
Copy link
Copy Markdown
Member Author

@jacobg I will check that. Let's focus on iOS in this PR. Did you had a chance to give it a try on iOS?

@jacobg
Copy link
Copy Markdown

jacobg commented Apr 20, 2026

@robingenz I figured out the issue was due to this PR using:

.package(url: "https://github.com/d-date/google-mlkit-swiftpm.git", .upToNextMinor(from: "8.0.0"))

whereas the latest version since January 2026 is version 9.

It caused two issues:

  1. Initially my app was already using version 9, and it caused a version conflict. So I removed my own direct dependency, and that resolve that issue.
  2. Version 8 uses GULISASwizzler from GoogleUtilities which was removed from the latest version of GoogleUtilities and whose version was not pinned to an older version.

I locally patched my node_modules for this PR to use version 9, and iOS works great now!

Did you intentionally use version 8, or are you ok if I create a PR with version 9?

@robingenz
Copy link
Copy Markdown
Member Author

@jacobg Thanks for the feedback. I used version 8 because that's the version we use with Cocoapods atm, see here. We usually only upgrade native deps with major releases.

@jacobg
Copy link
Copy Markdown

jacobg commented Apr 20, 2026

@robingenz There is some transitive dependency issue between MLKit and other Google/Firebase packages. It's discussed here:
d-date/google-mlkit-swiftpm#79
That PR was closed unmerged, because the GULISASwizzler had already been previously removed from this commit:
d-date/google-mlkit-swiftpm@a168a00

I'm not sure how you might see version 8 working now. Maybe it's because I also have direct dependencies on latest version of Firebase.

In any event, wouldn't this SPM PR be a major release that can coincide with updating to version 9?

@jacobg
Copy link
Copy Markdown

jacobg commented Apr 20, 2026

@robingenz
Copy link
Copy Markdown
Member Author

In any event, wouldn't this SPM PR be a major release that can coincide with updating to version 9?

Yes, we consider updating the native SDK a major change. I’ll update this PR to use ML Kit v9 so you can use the pre-release in the meantime, but we’ll need to hold off on merging until Capacitor 9 is published.

@jacobg
Copy link
Copy Markdown

jacobg commented Apr 20, 2026

@robingenz Oh I didn't know you were referring to major version of Capacitor. I thought you meant major version of capacitor-mlkit. So you tie the two together for major releases? Does that potentially stifle plugin innovation and cadence?

@robingenz
Copy link
Copy Markdown
Member Author

@jacobg Sure, that’s limiting, but it’s become the standard that the major version of Capacitor and its plugins match, to make it easier for developers to judge compatibility (see the official plugin versions).

@jacobg
Copy link
Copy Markdown

jacobg commented Apr 20, 2026

@robingenz ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants