ionic-native

Ionic-native5.x版本以上处理装饰器,在npm run build:esm的scripts命令里,有使用到scripts/build/transformers/plugin-class.ts文件里的方法来处理,这个后面再来研究。先写4.x版本的。

新建项目

1
2
3
4
5
6
7
8
9
$ npm install -g ionic
$ ionic start myApp
$ npm i -g cordova

#安装插件
$ ionic cordova plugin add cordova-plugin-camera
#移除插件
# ionic cordova plugin remove cordova-plugin-camera
$ npm install @ionic-native/camera --save

将插件引入app.module.ts文件的providers中。

WX20190814-204936@2x

业务模块内导入

WX20190814-205237@2x

页面

WX20190814-205308@2x

这边安装的@ionic-native与@ionic-native版本都是4.14.0

打包

连接手机

1
2
3
$ npm install -g ios-deploy
$ ionic cordova platform add ios
$ ionic cordova build ios

碰到第一个报错

1
2
npm ERR! ios-deploy@1.9.4 preinstall: `./src/scripts/check_reqs.js && xcodebuild`
npm ERR! Exit status 65

解决方案:

1
$ brew install ios-deploy

第二个问题

WX20190814-205910@2x

打包失败,没有证书,打开xcode,打开platforms/ios/MyApp.codeproj,配置证书,继续打包。

@ionic-native与@ionic-native/camera

@ionic-native/plugins/camera/index.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { Injectable } from '@angular/core';
import { Cordova, IonicNativePlugin, Plugin } from '@ionic-native/core';

export interface CameraOptions {
quality?: number;
destinationType?: number;
sourceType?: number;
allowEdit?: boolean;
encodingType?: number;
targetWidth?: number;
targetHeight?: number;
mediaType?: number;
correctOrientation?: boolean;
saveToPhotoAlbum?: boolean;
cameraDirection?: number;
popoverOptions?: CameraPopoverOptions;
}

export interface CameraPopoverOptions {
x: number;
y: number;
width: number;
height: number;
arrowDir: number;
}

export enum DestinationType {
DATA_URL = 0,
FILE_URL,
NATIVE_URI
}

export enum EncodingType {
JPEG = 0,
PNG
}

export enum MediaType {
PICTURE = 0,
VIDEO,
ALLMEDIA
}

export enum PictureSourceType {
PHOTOLIBRARY = 0,
CAMERA,
SAVEDPHOTOALBUM
}

export enum PopoverArrowDirection {
ARROW_UP = 1,
ARROW_DOWN,
ARROW_LEFT,
ARROW_RIGHT,
ARROW_ANY
}

export enum Direction {
BACK = 0,
FRONT
}

@Plugin({
pluginName: 'Camera',
plugin: 'cordova-plugin-camera',
pluginRef: 'navigator.camera',
repo: 'https://github.com/apache/cordova-plugin-camera',
platforms: ['Android', 'Browser', 'iOS', 'Windows']
})
@Injectable()
export class Camera extends IonicNativePlugin {
DestinationType = {
DATA_URL: 0,
FILE_URI: 1,
NATIVE_URI: 2
};

EncodingType = {
JPEG: 0,
PNG: 1
};

MediaType = {
PICTURE: 0,
VIDEO: 1,
ALLMEDIA: 2
};

PictureSourceType = {
PHOTOLIBRARY: 0,
CAMERA: 1,
SAVEDPHOTOALBUM: 2
};

PopoverArrowDirection = {
ARROW_UP: 1,
ARROW_DOWN: 2,
ARROW_LEFT: 4,
ARROW_RIGHT: 8,
ARROW_ANY: 15
};

Direction = {
BACK: 0,
FRONT: 1
};


@Cordova({
callbackOrder: 'reverse'
})
getPicture(options?: CameraOptions): Promise<any> {
return;
}

@Cordova({
platforms: ['iOS']
})
cleanup(): Promise<any> {
return;
}
}

主要看Plugin和Cordova装饰器

Plugin遍历了传入的config配置文件,为cls添加静态方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
export function Plugin(config: PluginConfig): ClassDecorator {
return (cls: any) => {
// Add these fields to the class
for (const prop in config) {
cls[prop] = config[prop];
}

cls['installed'] = (printWarning?: boolean) => {
return !!getPlugin(config.pluginRef);
};

cls['getPlugin'] = () => {
return getPlugin(config.pluginRef);
};

cls['checkInstall'] = () => {
return checkAvailability(cls) === true;
};

cls['getPluginName'] = () => {
return config.pluginName;
};

cls['getPluginRef'] = () => {
return config.pluginRef;
};

cls['getPluginInstallName'] = () => {
return config.plugin;
};

cls['getPluginRepo'] = () => {
return config.repo;
};

cls['getSupportedPlatforms'] = () => {
return config.platforms;
};

return cls;
};
}

而Cordova装饰器,在调用方法的时候会调用到wrap方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export function Cordova(opts: CordovaOptions = {}) {
return (
target: Object,
methodName: string,
descriptor: TypedPropertyDescriptor<any>
) => {
return {
value(...args: any[]) {
return wrap(this, methodName, opts).apply(this, args);
},
enumerable: true
};
};
}

调试

触发点击事件

WX20191030-212013@2x

获取插件实例

WX20191030-220527@2x

WX20191030-220613@2x

调用实例方法

WX20191030-220841@2x

WX20191030-220713@2x

postMessage通信

WX20191030-221034@2x

如果兼容多平台,可以考虑在get方法那配个映射表,修改获得的插件实例。