NativeScript 插件系统 #

插件概述 #

NativeScript 插件扩展了核心功能,提供对原生 API 的访问和额外的 UI 组件。

text
┌─────────────────────────────────────────────────────────────┐
│                    插件类型                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  JavaScript 插件                                            │
│  ├── 纯 JavaScript 实现                                     │
│  └── 无需原生代码                                           │
│                                                             │
│  原生插件                                                    │
│  ├── iOS: Swift/Objective-C                                 │
│  ├── Android: Kotlin/Java                                   │
│  └── 通过桥接访问原生 API                                   │
│                                                             │
│  UI 插件                                                    │
│  ├── 自定义 UI 组件                                         │
│  └── 封装原生视图                                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

安装插件 #

使用 npm 安装 #

bash
# 安装插件
ns plugin add @nativescript/camera

# 或使用 npm
npm install @nativescript/camera

插件命名规范 #

text
@nativescript/xxx     官方插件
nativescript-xxx      社区插件
@scope/nativescript-xxx  作用域插件

清理和重建 #

bash
# 清理项目
ns clean

# 重新添加平台
ns platform remove android
ns platform add android

常用官方插件 #

@nativescript/camera #

相机功能:

bash
ns plugin add @nativescript/camera
typescript
import { Camera } from '@nativescript/camera';

// 请求权限
await Camera.requestPermissions();

// 拍照
const image = await Camera.takePicture({
    width: 300,
    height: 300,
    keepAspectRatio: true,
    saveToGallery: true
});

// 从相册选择
const image = await Camera.pickFromGallery({
    width: 300,
    height: 300,
    keepAspectRatio: true
});

@nativescript/geolocation #

地理位置:

bash
ns plugin add @nativescript/geolocation
typescript
import { Geolocation } from '@nativescript/geolocation';

// 请求权限
await Geolocation.enableLocationRequest();

// 获取当前位置
const location = await Geolocation.getCurrentLocation({
    desiredAccuracy: Accuracy.high,
    maximumAge: 5000,
    timeout: 10000
});

console.log('Latitude:', location.latitude);
console.log('Longitude:', location.longitude);

// 监听位置变化
const watchId = Geolocation.watchLocation(
    (location) => {
        console.log('New location:', location);
    },
    (error) => {
        console.error('Error:', error);
    },
    {
        desiredAccuracy: Accuracy.high,
        updateDistance: 10,
        minimumUpdateTime: 1000
    }
);

// 停止监听
Geolocation.clearWatch(watchId);

@nativescript/social-share #

社交分享:

bash
ns plugin add @nativescript/social-share
typescript
import { SocialShare } from '@nativescript/social-share';

// 分享文本
SocialShare.shareText('Hello, World!');

// 分享图片
SocialShare.shareImage(image);

// 分享 URL
SocialShare.shareUrl('https://example.com', 'Example Site');

@nativescript/local-notifications #

本地通知:

bash
ns plugin add @nativescript/local-notifications
typescript
import { LocalNotifications } from '@nativescript/local-notifications';

// 请求权限
await LocalNotifications.requestPermission();

// 发送通知
LocalNotifications.schedule([{
    id: 1,
    title: 'Notification Title',
    body: 'Notification body text',
    at: new Date(Date.now() + 5000)
}]);

// 监听通知点击
LocalNotifications.addOnMessageReceivedCallback((notification) => {
    console.log('Notification received:', notification);
});

@nativescript/secure-storage #

安全存储:

bash
ns plugin add @nativescript/secure-storage
typescript
import { SecureStorage } from '@nativescript/secure-storage';

const secureStorage = new SecureStorage();

// 存储数据
await secureStorage.set({
    key: 'token',
    value: 'my-secret-token'
});

// 获取数据
const token = await secureStorage.get({
    key: 'token'
});

// 删除数据
await secureStorage.remove({
    key: 'token'
});

// 清空所有
await secureStorage.removeAll();

@nativescript/firebase #

Firebase 集成:

bash
ns plugin add @nativescript/firebase
typescript
import { firebase } from '@nativescript/firebase-core';
import '@nativescript/firebase-auth';
import '@nativescript/firebase-firestore';

// 初始化
firebase.initializeApp();

// 认证
const auth = firebase.auth();
await auth.signInWithEmailAndPassword(email, password);

// 数据库
const db = firebase.firestore();
const snapshot = await db.collection('users').get();

社区插件 #

nativescript-oauth2 #

OAuth 2.0 认证:

bash
ns plugin add nativescript-oauth2
typescript
import { TnsOAuthClient, TnsOAuthClientLogin } from 'nativescript-oauth2';

const client = new TnsOAuthClient('google');

client.loginWithCompletion((result, error) => {
    if (error) {
        console.error('Login failed:', error);
    } else {
        console.log('Access token:', result.accessToken);
    }
});

nativescript-image-cache #

图片缓存:

bash
ns plugin add nativescript-image-cache
xml
<NSImage src="https://example.com/image.jpg" 
         stretch="aspectFill" />

nativescript-pdf-view #

PDF 查看:

bash
ns plugin add nativescript-pdf-view
xml
<PDFView src="~/document.pdf" 
         load="onPdfLoaded" />

自定义插件开发 #

创建插件项目 #

bash
# 创建插件目录
mkdir nativescript-my-plugin
cd nativescript-my-plugin

# 初始化 npm
npm init -y

# 创建目录结构
mkdir -p platforms/android
mkdir -p platforms/ios

插件结构 #

text
nativescript-my-plugin/
├── platforms/
│   ├── android/
│   │   └── src/main/
│   │       └── java/com/example/
│   │           └── MyPlugin.java
│   └── ios/
│       └── MyPlugin.swift
├── index.d.ts          # TypeScript 定义
├── index.ts            # JavaScript 入口
├── package.json
└── README.md

JavaScript 入口 #

typescript
// index.ts
import { Application } from '@nativescript/core';

export class MyPlugin {
    static echo(value: string): string {
        if (global.isAndroid) {
            return com.example.MyPlugin.echo(value);
        } else {
            return MyPlugin.echo(value);
        }
    }
    
    static async doSomething(): Promise<string> {
        return new Promise((resolve, reject) => {
            // 原生实现
        });
    }
}

TypeScript 定义 #

typescript
// index.d.ts
export class MyPlugin {
    static echo(value: string): string;
    static doSomething(): Promise<string>;
}

Android 实现 #

java
// platforms/android/src/main/java/com/example/MyPlugin.java
package com.example;

public class MyPlugin {
    public static String echo(String value) {
        return "Echo: " + value;
    }
}

iOS 实现 #

swift
// platforms/ios/MyPlugin.swift
import Foundation

@objc(MyPlugin)
class MyPlugin: NSObject {
    @objc static func echo(_ value: String) -> String {
        return "Echo: \(value)"
    }
}

package.json 配置 #

json
{
    "name": "nativescript-my-plugin",
    "version": "1.0.0",
    "main": "index",
    "typings": "index.d.ts",
    "nativescript": {
        "platforms": {
            "android": "8.0.0",
            "ios": "8.0.0"
        }
    },
    "dependencies": {
        "@nativescript/core": "^8.0.0"
    }
}

原生 API 访问 #

直接访问 iOS API #

typescript
import { Utils } from '@nativescript/core';

// 获取 iOS 版本
const version = Utils.ios.MajorVersion;

// 访问 UIKit
const window = Utils.ios.getter(UIApplication, UIApplication.sharedApplication).keyWindow;

// 调用原生方法
const alert = UIAlertController.alertControllerWithTitleMessagePreferredStyle(
    "Title",
    "Message",
    UIAlertControllerStyle.Alert
);

直接访问 Android API #

typescript
import { Utils, Application } from '@nativescript/core';

// 获取 Android 版本
const version = android.os.Build.VERSION.SDK_INT;

// 获取 Context
const context = Application.android.context;

// 调用原生方法
const intent = new android.content.Intent(
    context,
    com.example.MyActivity.class
);
context.startActivity(intent);

插件调试 #

调试模式 #

bash
# 启动调试
ns debug android
ns debug ios

日志输出 #

typescript
console.log('Debug message');
console.warn('Warning message');
console.error('Error message');

原生日志 #

bash
# Android 日志
adb logcat | grep NativeScript

# iOS 日志
# 在 Xcode 控制台查看

插件发布 #

准备发布 #

bash
# 构建
npm run build

# 测试
npm test

# 检查
npm publish --dry-run

发布到 npm #

bash
# 登录 npm
npm login

# 发布
npm publish

# 发布 beta 版本
npm publish --tag beta

README 模板 #

markdown
# NativeScript My Plugin

## Installation
ns plugin add nativescript-my-plugin

## Usage
```typescript
import { MyPlugin } from 'nativescript-my-plugin';

const result = MyPlugin.echo('Hello');

API #

echo(value: string): string #

Echoes the input value.

License #

MIT

text

## 最佳实践

### 插件设计原则

┌─────────────────────────────────────────────────────────────┐ │ 插件设计原则 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 1. 简洁 API │ │ 提供简单易用的接口 │ │ │ │ 2. 跨平台一致性 │ │ iOS 和 Android 行为一致 │ │ │ │ 3. 错误处理 │ │ 统一的错误处理机制 │ │ │ │ 4. 类型定义 │ │ 提供完整的 TypeScript 定义 │ │ │ │ 5. 文档完善 │ │ 详细的使用说明和示例 │ │ │ │ 6. 版本兼容 │ │ 说明兼容的 NativeScript 版本 │ │ │ └─────────────────────────────────────────────────────────────┘

text

### 权限处理

```typescript
import { Application } from '@nativescript/core';

export class PermissionHelper {
    static async requestCameraPermission(): Promise<boolean> {
        if (global.isAndroid) {
            return await this.requestAndroidPermission(
                android.Manifest.permission.CAMERA
            );
        } else {
            return await this.requestIOSPermission('camera');
        }
    }
    
    private static async requestAndroidPermission(permission: string): Promise<boolean> {
        return new Promise((resolve) => {
            Application.android.on(Application.android.activityRequestPermissionsEvent, (args) => {
                resolve(args.grantResults[0] === android.content.pm.PackageManager.PERMISSION_GRANTED);
            });
            
            (Application.android.foregroundActivity || Application.android.startActivity)
                .requestPermissions([permission], 0);
        });
    }
}

下一步 #

现在你已经掌握了插件系统,接下来学习 网络请求,了解如何进行 API 调用!

最后更新:2026-03-29