关于 capacitor-plugin-spm-support
这项技能指导开发者为现有 Capacitor 插件添加 Swift Package Manager 支持,包括替换 Objective-C 桥接、创建包清单并验证 iOS 构建。
主要功能
- 01检查插件元数据与依赖
- 02创建 Package.swift 清单
- 03通过 CAPBridgedPlugin 注册方法
- 04移除 Objective-C 桥接引用
- 05更新包文件并验证构建
适用场景
- 01为现有 iOS 插件添加 SPM 分发
- 02将插件注册从 Objective-C 迁至 Swift
- 03检查 SPM 依赖和项目文件变更
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ capawesome-team/ skills --skill capacitor-plugin-spm-support安装后在 Claude Code 中输入/capacitor-plugin-spm-support确认已加载。
详细介绍
为 Capacitor 插件添加 SPM 支持
通过将 Objective-C 桥接替换为 CAPBridgedPlugin Swift 协议,并添加 Package.swift 清单,为现有 Capacitor 插件添加 Swift Package Manager(SPM)支持。
前提条件
| 要求 | 版本 |
|---|---|
| Capacitor | 6+ |
| Swift | 5.9+ |
| Xcode | 15+ |
项目必须是 Capacitor 插件(而非应用项目)。插件必须已有 iOS 实现,且 Swift 源文件位于 ios/Plugin/ 中。
操作步骤
第 1 步:收集插件信息
- 阅读插件根目录中的
package.json。提取:- 插件包名称(例如,
@capawesome/capacitor-app-review)。 - 现有的
files数组条目。 - 现有的
scripts条目。
- 插件包名称(例如,
- 阅读插件根目录中的
.podspec文件。提取:- Pod 名称(
Pod::Spec.new参数,例如,CapawesomeCapacitorAppReview)。这将成为 SPM 包名称。 - iOS 部署目标,取自
s.ios.deployment_target(例如,'13.0')。提取主版本号(例如,13)。这将成为 SPM iOS 版本。 - 所有第三方 CocoaPods 依赖项——任何不是
Capacitor或CapacitorCordova的s.dependency或spec.dependency条目。记录每项依赖的名称和版本约束。
- Pod 名称(
- 找出
ios/Plugin/中的插件 Swift 文件。该文件包含一个扩展CAPPlugin且带有@objc(<PluginClassName>)的类。提取:- 插件类名(例如,
AppReviewPlugin)。 - 来自 Objective-C
.m文件中CAP_PLUGIN宏第一个字符串参数的 JavaScript 名称(例如,AppReview)。 .m文件中CAP_PLUGIN_METHOD宏调用里的所有插件方法,并记录每个方法的名称和返回类型(例如,CAPPluginReturnPromise)。
- 插件类名(例如,
- 找出
ios/Plugin/中的 Objective-C 桥接文件:<PluginClassName>.h(头文件)<PluginClassName>.m(包含CAP_PLUGIN宏的实现文件)
- 从
package.json读取 Capacitor 对等依赖版本(peerDependencies["@capacitor/core"])。确定主版本号(例如,6)。这就是 Capacitor 主版本号。
第 2 步:为 SPM 确定 CocoaPods 依赖项
如果第 1 步未发现第三方 CocoaPods 依赖项,则跳过此步骤。
每项第三方 CocoaPods 依赖都需要一个兼容 SPM 的等效包。向用户列出这些依赖项,并询问他们是否可以提供 SPM 包 URL,或者是否需要 Agent 搜索网络以查找 SPM 等效包。
**如果用户提供 SPM 包 URL:**记录这些 URL,然后继续第 3 步。
**如果用户要求搜索网络:**针对每项 CocoaPods 依赖:
- 在网络上搜索
"<dependency_name>" Swift Package Manager,以确认原始 CocoaPods 依赖是否也支持 SPM。许多常见库(例如,Firebase、Alamofire)通过同一仓库同时分发 CocoaPods 和 SPM 包。 - 如果原始库支持 SPM,则使用其 Git 仓库 URL。版本应与 podspec 中指定的版本相同——将 CocoaPods 版本约束转换为对应的 SPM 格式(例如,
~> 5.0转换为.upToNextMajor(from: "5.0.0"),= 2.1.0转换为.exact("2.1.0"))。 - 如果原始库不支持 SPM,则搜索
"<dependency_name>" SPM alternative,以寻找可通过 SPM 提供等效功能的替代包。所用版本必须与 podspec 中使用的版本兼容。 - 如果不存在兼容 SPM 的替代方案,请告知用户并询问如何继续。
记录每项依赖对应的 SPM 包 URL、版本要求和产品名称。下一步会将这些内容添加到 Package.swift 中。
第 3 步:创建 Package.swift
在插件根目录中创建 Package.swift,内容如下:
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "<SPM_PACKAGE_NAME>",
platforms: [.iOS(.v<SPM_IOS_VERSION>)],
products: [
.library(
name: "<SPM_PACKAGE_NAME>",
targets: ["<PLUGIN_CLASS_NAME>"])
],
dependencies: [
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", branch: "<CAPACITOR_MAJOR_VERSION>.0.0")
// <ADDITIONAL_PACKAGE_DEPENDENCIES>
],
targets: [
.target(
name: "<PLUGIN_CLASS_NAME>",
dependencies: [
.product(name: "Capacitor", package: "capacitor-swift-pm"),
.product(name: "Cordova", package: "capacitor-swift-pm")
// <ADDITIONAL_TARGET_DEPENDENCIES>
],
path: "ios/Plugin"),
.testTarget(
name: "<PLUGIN_CLASS_NAME>Tests",
dependencies: ["<PLUGIN_CLASS_NAME>"],
path: "ios/PluginTests")
]
)
替换所有占位符:
<SPM_IOS_VERSION>— 第 1 步中的 SPM iOS 版本(例如,13)。<SPM_PACKAGE_NAME>— 第 1 步中的 pod 名称(例如,CapawesomeCapacitorAppReview)。<PLUGIN_CLASS_NAME>— 第 1 步中的插件类名称(例如,AppReviewPlugin)。<CAPACITOR_MAJOR_VERSION>— 第 1 步中的 Capacitor 主版本号(例如,6)。<ADDITIONAL_PACKAGE_DEPENDENCIES>— 如果第 2 步中解析出了第三方依赖项,则为每个依赖项添加一个.package(url: "<repo_url>", <version_requirement>)条目。如果没有额外依赖项,则删除注释行。<ADDITIONAL_TARGET_DEPENDENCIES>— 为上面添加的每个 package 依赖项添加对应的.product(name: "<ProductName>", package: "<package-name>")条目。如果没有额外依赖项,则删除注释行。
第 4 步:更新 Swift 插件类
打开插件 Swift 文件(例如,ios/Plugin/<PluginClassName>.swift)。
- 在类声明中添加
CAPBridgedPlugin协议遵循。 - 将三个必需属性添加为类体中的第一个属性,放在任何现有属性之前。
应用以下 diff 模式:
@objc(<PluginClassName>)
-public class <PluginClassName>: CAPPlugin {
+public class <PluginClassName>: CAPPlugin, CAPBridgedPlugin {
+ public let identifier = "<PluginClassName>"
+ public let jsName = "<JS_NAME>"
+ public let pluginMethods: [CAPPluginMethod] = [
+ CAPPluginMethod(name: "<method1>", returnType: CAPPluginReturnPromise),
+ CAPPluginMethod(name: "<method2>", returnType: CAPPluginReturnPromise)
+ ]
替换:
<PluginClassName>— 插件类名称(例如,AppReviewPlugin)。<JS_NAME>—.m文件的CAP_PLUGIN宏中的 JavaScript 名称(例如,AppReview)。pluginMethods数组 — 列出.m文件的CAP_PLUGIN_METHOD调用中的所有方法,并准确保留每个方法的名称和返回类型。
第 5 步:删除 Objective-C 桥接文件
从 ios/Plugin/ 中删除以下文件:
<PluginClassName>.h<PluginClassName>.m
由于插件注册现在由 Swift 中的 CAPBridgedPlugin 协议处理,因此不再需要这些文件。
第 6 步:清理 Xcode 项目文件
打开 ios/Plugin.xcodeproj/project.pbxproj,并删除所有指向已删除 Objective-C 文件的引用。具体来说,删除引用以下文件的行:
<PluginClassName>.h— 文件引用、构建阶段条目(PBXBuildFile、PBXFileReference、PBXGroup子项、PBXHeadersBuildPhase)<PluginClassName>.m— 文件引用、构建阶段条目(PBXBuildFile、PBXFileReference、PBXGroup子项、PBXSourcesBuildPhase)
在 .pbxproj 文件中搜索这两个文件名,并删除每一行引用它们的行。
第 7 步:更新 .gitignore
打开插件根目录中的 .gitignore。如果以下条目尚不存在,则添加它们:
# iOS files
+Package.resolved
+/.build
+/Packages
+.swiftpm/configuration/registries.json
+.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
+.netrc
将这些条目放在 .gitignore 文件的 iOS 部分,位于任何现有 iOS 相关条目(例如 Pods、Podfile.lock)之后。
第 8 步:更新 package.json
对 package.json 进行两处修改:
- 将
"Package.swift"添加到files数组中:
"ios/Plugin/",
- "<PodName>.podspec"
+ "<PodName>.podspec",
+ "Package.swift"
],
- 将
ios:spm:install脚本添加到scripts对象中:
"ios:pod:install": "cd ios && pod install --repo-update && cd ..",
+ "ios:spm:install": "cd ios && swift package resolve && cd ..",
如果不存在 ios:pod:install 脚本,则将 ios:spm:install 脚本添加在最后一个现有脚本条目之后。
第 9 步:验证
- 在插件根目录中运行
npm install,以确保package.json有效。 - 通过构建插件的示例应用或测试应用,验证 iOS 构建仍能成功。
错误处理
- 如果移除 ObjC 引用后
.pbxproj文件损坏,请从版本控制中恢复,并仔细重新编辑,确保只删除完整的行。 - 如果 Swift 构建失败并提示找不到
CAPBridgedPlugin,请确认@capacitor/core的版本为 6+,且capacitor-swift-pm分支与 Capacitor 主版本匹配。 - 如果 SPM 解析失败(
swift package resolve),请确认Package.swift中的目标路径与实际目录结构相符(源文件位于ios/Plugin,测试文件位于ios/PluginTests)。 - 如果插件没有测试目标目录(
ios/PluginTests),请从Package.swift中移除.testTarget块。 - 如果插件除了主插件文件外还有其他 Swift 源文件,则无需额外修改;SPM 会自动包含目标路径中的所有
.swift文件。 - 如果
.m文件中的某些方法使用CAPPluginReturnNone而非CAPPluginReturnPromise,请在pluginMethods数组中保留原始返回类型。 - 如果某个 CocoaPods 依赖没有对应的 SPM 版本,且找不到替代方案,则该插件无法完全支持 SPM。请告知用户,并建议他们自行引入该依赖的源代码,或等待上游支持 SPM。
相关技能
capacitor-plugin-development— 用于从头创建新的 Capacitor 插件,包括搭建脚手架、原生实现和发布。capacitor-plugin-upgrades— 用于将 Capacitor 插件升级到更新的主版本。