跳到主要内容
版本:v5

将插件升级至Capacitor 3.0

对于需要升级到Capacitor 3的插件,我们提供以下必要和推荐的修改方案。

核心API规划

当前核心团队在修改Capacitor内部实现时,可能会对插件造成影响。由于Capacitor 2中iOS和Android的大部分类和方法都是公开的,我们观察到存在不符合预期的API使用情况。

在Capacitor 3开发过程中,我们将评估该问题并建立官方公共API,相关文档将发布于此处

Android端修改

使用新版@CapacitorPlugin注解

@NativePlugin注解已弃用。推荐使用新的@CapacitorPlugin注解以支持新版权限API

name属性保持不变。移除requestCodespermissionRequestCode属性。permissions属性需替换为@Permission注解列表(每个注解包含manifest字符串列表及其对应的alias,在实现新版权限API前可暂不设置别名)。

-@NativePlugin(
+@CapacitorPlugin(
name = "FooBar",
- requestCodes = {
- FooBarPlugin.REQUEST_SOME_METHOD,
- FooBarPlugin.REQUEST_SOME_OTHER_METHOD
- },
- permissionRequestCode = FooBarPlugin.REQUEST_ALL_PERMISSIONS,
- permissions = { Manifest.permission.FOO, Manifest.permission.BAR }
+ permissions = {
+ @Permission(strings = { Manifest.permission.FOO }, alias = "foo"),
+ @Permission(strings = { Manifest.permission.BAR }, alias = "bar")
+ })
)
public class FooBarPlugin extends Plugin {
static final int REQUEST_SOME_METHOD = 10051;
static final int REQUEST_SOME_OTHER_METHOD = 10052;

Android请求码处理

Capacitor 3.0采用AndroidX Activity Result API,移除了手动定义请求码的方式。现在应使用@ActivityCallback@PermissionCallback注解提供回调方法,这些回调可在启动新Activity或权限请求时引用。

-static final int IMAGE_REQUEST = 10052;

@PluginMethod
public void chooseImage(PluginCall call) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
- startActivityForResult(call, intent, IMAGE_REQUEST);
+ startActivityForResult(call, intent, "chooseImageResult");
}

+@ActivityCallback
+private void chooseImageResult(PluginCall call, ActivityResult result) {
+ if (result.getResultCode() == Activity.RESULT_CANCELED) {
+ call.reject("用户取消操作");
+ } else {
+ Intent data = result.getData();
+ // 处理返回数据
+ call.resolve("操作成功");
+ }
+}

使用WebColor.parseColor()替代Color.parseColor()

Android解析带alpha通道的十六进制颜色字符串为ARGB格式,而iOS和Web端解析为RGBA格式。如需跨平台共享带透明通道的颜色值,请使用新的WebColor工具类。WebColor.parseColor()功能类似原生Android的Color.parseColor(),但会按照RGBA格式解析字符串。

String colorStringWithAlpha = "#FF000088"; // 半透明红色
int color = WebColor.parseColor(colorStringWithAlpha);

若颜色不包含alpha通道,两个方法将返回相同结果。

将默认compileSdkVersion和targetSdkVersion更新至30

修改android/build.gradle中的默认值为30:

android {
- compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 29
+ compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 30
defaultConfig {
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 21
- targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 29
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 30
...
}
...
}

iOS端修改

弱引用处理

Capacitor 3优化了对象关系以修复内存泄漏问题。插件对层级更高对象的引用现在改为weak(在Swift中表现为可选类型)。最常见的场景是访问bridge属性,但该变化同样适用于webView等属性。调用bridge方法时需使用可选链:

-bridge.presentVC(myViewController, animated: true, completion: nil)
+bridge?.presentVC(myViewController, animated: true, completion: nil)

该变化的最大影响是bridge的所有返回值都将变为可选类型。正确处理可选类型可能需要额外步骤

Bridge接口变更

除了引用类型变化外,bridge的API也进行了更新(现通过正式协议暴露)。许多属性和方法已重命名,但保留了旧接口的向后兼容支持。Xcode在多数情况下会自动提示新接口。建议迁移现有代码以消除编译警告。

CAPPluginCall参数处理

Capacitor提供了一系列便捷方法(getStringgetDate等)来访问JavaScript传递的数据,这些方法在3.0版本中进行了更新:

  • 移除get()方法,可直接读取options字典
  • 弃用hasOption,建议使用类型化访问器
  • 所有带默认值的访问器现在要求非可选默认值,并返回非可选结果
  • 日期和null值的处理逻辑有所调整(详见数据类型文档
  • Objective-C便捷访问器已分离以避免冲突,需通过#import <Capacitor/CAPBridgedJSTypes.h>导入

PluginCall & CAPPluginCall变更

使用resolve()reject()

推荐使用resolve()reject()来替代已弃用的success()error(),这更符合插件方法的Promise式流程设计。

无参resolve()现在返回undefined

此前无参数调用resolve()会返回空对象,为保持与JavaScript的Promise.resolve()行为一致,3.0版本改为返回undefined

调用保持机制

弃用save()方法,新增keepAlive属性替代。详细文档说明阐明了推荐的使用模式。

设置iOS部署目标为12.0

在Xcode项目的Build Settings标签页中,将Deployment部分的iOS Deployment Target修改为12.0

同时更新Podfile和podspec文件中的iOS版本:

-platform :ios, '11.0'
+platform :ios, '12.0'
use_frameworks!
-s.ios.deployment_target  = '11.0'
+s.ios.deployment_target = '12.0'

设置Swift版本为5

在Xcode目标的Build Settings中,将Swift Compiler - Language部分的Swift Language Version修改为Swift 5

同时更新podspec文件:

-s.swift_version = '4.2'
+s.swift_version = '5.1'

Web端修改

插件注册方式

弃用registerWebPlugin(MyPlugin)函数,推荐使用新的registerPlugin函数并惰性加载web(可选electron)插件:

import { registerPlugin } from '@capacitor/core';
import type { CoolPlugin } from './definitions';

const MyCoolPlugin = registerPlugin<CoolPlugin>('MyCoolPlugin', {
web: () => import('./web').then((m) => new m.MyCoolPluginWeb()),
// electron: () => ("./electron").then(m => new m.MyCoolPluginElectron())
});

export * from './definitions';
export { MyCoolPlugin };

设置TypeScript输出目标为es2017

建议在tsconfig.json中将输出目标设置为es2017

错误处理优化

推荐插件开发者使用Capacitor 3新增的错误码:

  • Unavailable:表示功能当前不可用
  • Unimplemented:表示功能无法或不会实现

详细指南参见WebiOSAndroid文档。

采用新版权限接口

3.0之前版本会在首次使用功能时自动请求权限。Capacitor 3允许应用开发者随时检查或请求权限,从而更灵活地控制用户提示的显示时机。

虽然仍可自动请求权限,但建议采用新的权限模式以提供更好的用户体验控制。

了解如何在插件中实现权限API ›