插件概述 #
一、插件系统简介 #
1.1 什么是插件 #
Capacitor插件是封装原生功能的模块,允许JavaScript代码调用iOS、Android和Web平台的原生能力。插件提供了统一的API接口,屏蔽了平台差异。
text
┌─────────────────────────────────────────────────────────────┐
│ JavaScript API │
│ (统一的调用接口) │
├─────────────────────────────────────────────────────────────┤
│ Plugin Layer │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ iOS Plugin │ │Android Plugin │ │ Web Plugin │ │
│ │ (Swift) │ │ (Java) │ │ (TypeScript) │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Native Platform APIs │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ iOS SDK │ │ Android SDK │ │ Web APIs │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────────────┘
1.2 插件类型 #
| 类型 | 说明 | 示例 |
|---|---|---|
| 官方插件 | Capacitor团队维护 | @capacitor/camera |
| 社区插件 | 社区开发者贡献 | capacitor-plugin-biometric |
| 自定义插件 | 项目内部开发 | @mycompany/custom-plugin |
| Cordova插件 | 兼容Cordova生态 | cordova-plugin-geolocation |
1.3 插件优势 #
| 优势 | 说明 |
|---|---|
| 跨平台一致 | 统一的JavaScript API |
| 类型安全 | 完整的TypeScript支持 |
| 按需加载 | 只加载需要的插件 |
| 易于扩展 | 可开发自定义插件 |
| 原生性能 | 直接调用原生API |
二、插件架构 #
2.1 插件结构 #
text
@capacitor/plugin-name/
├── dist/ # 编译输出
│ ├── esm/ # ES模块
│ ├── cjs/ # CommonJS模块
│ └── definitions.d.ts # 类型定义
│
├── src/
│ ├── definitions.ts # 接口定义
│ ├── index.ts # 入口文件
│ ├── web.ts # Web实现
│ └── index.ts # 导出
│
├── ios/
│ ├── Sources/
│ │ └── PluginName/
│ │ ├── PluginName.h
│ │ └── PluginName.m
│ └── PluginName.podspec # CocoaPods配置
│
├── android/
│ └── src/
│ └── main/
│ ├── java/com/example/plugin/
│ │ └── PluginName.java
│ └── AndroidManifest.xml
│
├── package.json
├── tsconfig.json
└── README.md
2.2 插件接口定义 #
typescript
// src/definitions.ts
export interface MyPlugin {
// 方法定义
doSomething(options: DoSomethingOptions): Promise<DoSomethingResult>;
// 事件监听
addListener(eventName: 'myEvent', listener: (data: MyEventData) => void): Promise<void>;
// 移除监听
removeAllListeners(): Promise<void>;
}
// 选项接口
export interface DoSomethingOptions {
param1: string;
param2?: number;
}
// 结果接口
export interface DoSomethingResult {
success: boolean;
data?: any;
}
// 事件数据接口
export interface MyEventData {
message: string;
timestamp: number;
}
2.3 插件注册 #
typescript
// src/index.ts
import { registerPlugin } from '@capacitor/core';
import type { MyPlugin } from './definitions';
import { MyPluginWeb } from './web';
// 注册插件
const MyPlugin = registerPlugin<MyPlugin>('MyPlugin', {
web: () => import('./web').then(m => new m.MyPluginWeb())
});
export * from './definitions';
export { MyPlugin };
三、官方插件 #
3.1 核心插件列表 #
| 插件 | 功能 | 平台支持 |
|---|---|---|
| @capacitor/camera | 相机与相册 | iOS, Android, Web |
| @capacitor/geolocation | 地理定位 | iOS, Android, Web |
| @capacitor/storage | 本地存储 | iOS, Android, Web |
| @capacitor/device | 设备信息 | iOS, Android, Web |
| @capacitor/network | 网络状态 | iOS, Android, Web |
| @capacitor/push-notifications | 推送通知 | iOS, Android |
| @capacitor/local-notifications | 本地通知 | iOS, Android |
| @capacitor/share | 系统分享 | iOS, Android, Web |
| @capacitor/clipboard | 剪贴板 | iOS, Android, Web |
| @capacitor/haptics | 触觉反馈 | iOS, Android |
| @capacitor/status-bar | 状态栏 | iOS, Android |
| @capacitor/splash-screen | 启动画面 | iOS, Android |
| @capacitor/keyboard | 键盘控制 | iOS, Android |
| @capacitor/browser | 浏览器 | iOS, Android, Web |
| @capacitor/app | 应用信息 | iOS, Android, Web |
| @capacitor/filesystem | 文件系统 | iOS, Android, Web |
| @capacitor/preferences | 偏好设置 | iOS, Android, Web |
| @capacitor/action-sheet | 操作菜单 | iOS, Android, Web |
| @capacitor/dialog | 对话框 | iOS, Android, Web |
| @capacitor/toast | 提示消息 | iOS, Android, Web |
3.2 安装官方插件 #
bash
# 安装相机插件
npm install @capacitor/camera
# 安装地理位置插件
npm install @capacitor/geolocation
# 安装存储插件
npm install @capacitor/preferences
# 同步原生项目
npx cap sync
3.3 使用官方插件 #
typescript
// 相机插件
import { Camera, CameraResultType } from '@capacitor/camera';
async function takePhoto() {
const photo = await Camera.getPhoto({
quality: 90,
allowEditing: true,
resultType: CameraResultType.Uri
});
return photo.webPath;
}
// 地理位置插件
import { Geolocation } from '@capacitor/geolocation';
async function getCurrentPosition() {
const position = await Geolocation.getCurrentPosition();
return {
latitude: position.coords.latitude,
longitude: position.coords.longitude
};
}
// 存储插件
import { Preferences } from '@capacitor/preferences';
async function saveData(key: string, value: string) {
await Preferences.set({ key, value });
}
async function getData(key: string) {
const { value } = await Preferences.get({ key });
return value;
}
四、社区插件 #
4.1 查找社区插件 #
4.2 常用社区插件 #
| 插件 | 功能 |
|---|---|
| @capacitor-community/firebase-analytics | Firebase分析 |
| @capacitor-community/firebase-crashlytics | Firebase崩溃报告 |
| @capacitor-community/sqlite | SQLite数据库 |
| @capacitor-community/http | HTTP请求 |
| @capacitor-community/stripe | Stripe支付 |
| @capacitor-community/facebook-login | Facebook登录 |
| @capacitor-community/google-signin | Google登录 |
| @capacitor-community/admob | AdMob广告 |
| @capacitor-community/appcenter | App Center |
| @capacitor-community/intercom | Intercom客服 |
4.3 安装社区插件 #
bash
# 安装Firebase分析
npm install @capacitor-community/firebase-analytics
# 安装SQLite
npm install @capacitor-community/sqlite
# 同步
npx cap sync
五、Cordova插件兼容 #
5.1 兼容性说明 #
Capacitor支持大多数Cordova插件,但推荐优先使用Capacitor原生插件。
5.2 安装Cordova插件 #
bash
# 安装Cordova插件
npm install cordova-plugin-device-name
# 同步
npx cap sync
5.3 使用Cordova插件 #
typescript
// 声明全局变量
declare global {
interface Window {
device: any;
}
}
// 使用
if (window.device) {
console.log('Device name:', window.device.name);
}
5.4 兼容性检查 #
bash
# 检查插件兼容性
npx cap plugin:check
六、插件开发基础 #
6.1 创建插件项目 #
bash
# 使用Capacitor CLI创建插件
npm init @capacitor/plugin my-plugin
# 按提示输入信息
# ? Plugin NPM name: @mycompany/my-plugin
# ? Plugin id: my-plugin
# ? Plugin description: My custom Capacitor plugin
# ? Plugin git repository:
# ? Plugin author:
# ? Plugin license: MIT
# ? Package type: npm
6.2 插件项目结构 #
text
my-plugin/
├── src/
│ ├── definitions.ts # 接口定义
│ ├── index.ts # 入口
│ └── web.ts # Web实现
│
├── ios/
│ ├── Sources/
│ │ └── MyPlugin/
│ │ ├── MyPlugin.swift
│ │ └── MyPlugin.m
│ └── MyPlugin.podspec
│
├── android/
│ └── src/main/
│ └── java/com/mycompany/myplugin/
│ └── MyPlugin.java
│
├── package.json
├── tsconfig.json
├── rollup.config.js
└── README.md
6.3 定义插件接口 #
typescript
// src/definitions.ts
import type { PluginListenerHandle } from '@capacitor/core';
export interface MyPlugin {
// 基本方法
echo(options: { value: string }): Promise<{ value: string }>;
// 带选项的方法
doSomething(options: DoSomethingOptions): Promise<DoSomethingResult>;
// 事件监听
addListener(
eventName: 'myEvent',
listener: (data: MyEventData) => void
): Promise<PluginListenerHandle>;
// 移除所有监听器
removeAllListeners(): Promise<void>;
}
export interface DoSomethingOptions {
param1: string;
param2?: number;
flag?: boolean;
}
export interface DoSomethingResult {
success: boolean;
message: string;
data?: any;
}
export interface MyEventData {
type: string;
payload: any;
}
6.4 Web实现 #
typescript
// src/web.ts
import { WebPlugin } from '@capacitor/core';
import type { MyPlugin, DoSomethingOptions, DoSomethingResult, MyEventData } from './definitions';
export class MyPluginWeb extends WebPlugin implements MyPlugin {
async echo(options: { value: string }): Promise<{ value: string }> {
return { value: options.value };
}
async doSomething(options: DoSomethingOptions): Promise<DoSomethingResult> {
console.log('doSomething called with:', options);
// Web实现逻辑
return {
success: true,
message: 'Operation completed',
data: { input: options }
};
}
// 触发事件示例
notifyEvent(data: MyEventData) {
this.notifyListeners('myEvent', data);
}
}
6.5 插件注册 #
typescript
// src/index.ts
import { registerPlugin } from '@capacitor/core';
import type { MyPlugin } from './definitions';
const MyPlugin = registerPlugin<MyPlugin>('MyPlugin', {
web: () => import('./web').then(m => new m.MyPluginWeb())
});
export * from './definitions';
export { MyPlugin };
七、插件使用模式 #
7.1 Promise模式 #
typescript
// 最常用的异步调用模式
const result = await MyPlugin.doSomething({
param1: 'value',
param2: 123
});
console.log(result.success);
7.2 事件监听模式 #
typescript
// 添加监听器
const listener = await MyPlugin.addListener('myEvent', (data) => {
console.log('Event received:', data);
});
// 移除监听器
await listener.remove();
// 移除所有监听器
await MyPlugin.removeAllListeners();
7.3 回调模式 #
typescript
// 某些插件支持回调
MyPlugin.watchPosition({}, (position) => {
console.log('Position:', position);
});
// 清除监听
await MyPlugin.clearWatch();
八、插件权限 #
8.1 iOS权限配置 #
xml
<!-- ios/App/App/Info.plist -->
<key>NSCameraUsageDescription</key>
<string>需要访问相机来拍照</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册来选择照片</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>需要获取您的位置信息</string>
8.2 Android权限配置 #
xml
<!-- android/app/src/main/AndroidManifest.xml -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
8.3 运行时权限请求 #
typescript
import { Camera } from '@capacitor/camera';
// 请求权限
async function requestCameraPermission() {
const permission = await Camera.requestPermissions();
if (permission.camera === 'granted') {
// 权限已授予
const photo = await Camera.getPhoto();
} else {
// 权限被拒绝
console.log('Camera permission denied');
}
}
九、插件调试 #
9.1 控制台日志 #
typescript
// 在插件中添加日志
export class MyPluginWeb extends WebPlugin implements MyPlugin {
async doSomething(options: DoSomethingOptions): Promise<DoSomethingResult> {
console.log('[MyPlugin] doSomething called:', options);
// ... 实现逻辑
console.log('[MyPlugin] doSomething result:', result);
return result;
}
}
9.2 原生调试 #
iOS:
swift
// Swift日志
print("[MyPlugin] doSomething called with: \(options)")
Android:
java
// Java日志
Log.d("MyPlugin", "doSomething called with: " + options.toString());
9.3 Web调试 #
typescript
// 开发模式下启用详细日志
if (import.meta.env.DEV) {
const originalCall = MyPlugin.doSomething;
MyPlugin.doSomething = async (options) => {
console.time('doSomething');
const result = await originalCall(options);
console.timeEnd('doSomething');
return result;
};
}
十、插件最佳实践 #
10.1 API设计原则 #
| 原则 | 说明 |
|---|---|
| 一致性 | 遵循官方插件的命名和风格 |
| 简洁性 | 提供简单易用的API |
| 类型安全 | 完整的TypeScript类型定义 |
| 错误处理 | 清晰的错误信息和错误码 |
| 文档完善 | 提供详细的使用文档 |
10.2 错误处理 #
typescript
// 定义错误类型
export class MyPluginError extends Error {
constructor(
message: string,
public code: string,
public data?: any
) {
super(message);
this.name = 'MyPluginError';
}
}
// 使用
async doSomething(options: DoSomethingOptions): Promise<DoSomethingResult> {
if (!options.param1) {
throw new MyPluginError('param1 is required', 'INVALID_ARGUMENT');
}
try {
// 执行操作
return { success: true, message: 'OK' };
} catch (error) {
throw new MyPluginError(
error.message,
'OPERATION_FAILED',
{ originalError: error }
);
}
}
10.3 版本兼容 #
typescript
// 检查API可用性
async checkAvailability(): Promise<boolean> {
try {
await MyPlugin.echo({ value: 'test' });
return true;
} catch {
return false;
}
}
十一、总结 #
11.1 插件系统要点 #
| 要点 | 说明 |
|---|---|
| 统一API | 跨平台一致的JavaScript接口 |
| 类型安全 | 完整的TypeScript支持 |
| 按需加载 | 只加载需要的平台实现 |
| 易于扩展 | 可开发自定义插件 |
11.2 下一步 #
了解插件概述后,让我们学习 官方插件 的详细使用!
最后更新:2026-03-28