专注于
IT技术和业内交流

Cordova iOS平台的插件开发(一)

我们先看一下cordova插件的文件夹,都包括哪些目录以及文件。这里我以Device插件为例:

插件目录

Device插件目录结构

因为是官方的插件所以目录和文件比较多,我们在实际开发中可以适当的增删,不过有些是必须要有的。

src

目录里面放对应不同平台的文件,andorid是java,iOS是.h和.m文件

www

文件夹下放我们的javascript文件。

plugin.xml

插件的配置文件。

plugin.xml

<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
    xmlns:rim="http://www.blackberry.com/ns/widgets"
    xmlns:android="http://schemas.android.com/apk/res/android"
    id="cordova-plugin-device"
    version="1.1.1">
    <name>Device</name>
    <description>Cordova Device Plugin</description>
    <license>Apache 2.0</license>
    <keywords>cordova,device</keywords>
    <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git</repo>
    <issue>https://issues.apache.org/jira/browse/CB/component/12320648</issue>

<js-module src="www/device.js" name="device">
        <clobbers target="device" />
    </js-module>
    ...

主要的几个属性

Attributes(type) Description
xmlns The plugin namespace, http://apache.org/cordova/ns/plugins/ 1.0. If the document contains XML from other namespaces, such as tags to be added to the AndroidManifest.xml file in the case of Android, those namespaces should also be included in the element.
id A npm-style identifier for the plugin.
version A version number for the plugin. Semver syntax is supported.
name specify the name of the plugin
description specify the description of the plugin.
keyWords contains comma separated keywords to describe the plugin
keyWords specify the license of the plugin
js-module specifies the path to the common JavaScript interface
  <platform name="ios">
        <config-file target="config.xml" parent="/*">
            <feature name="Device">
                <param name="ios-package" value="CDVDevice"/>
            </feature>
        </config-file>
        <header-file src="src/ios/CDVDevice.h" />
        <source-file src="src/ios/CDVDevice.m" />
    </platform>

这里是插件的配置信息(iOS为例子)的插件信息插入到平台的 config.xml 文件中,来通知平台添加了插件.

插件的调用过程

要开发自己的cordova插件,了解一下插件的调用过程是非常有必要的。下面是简单介绍一下。

首先我们在js中调用device的方法,获取设备信息。

        App.uuid = device.uuid;
        // 设备的模型或产品的名称
        App.model = device.model;
        // 系统版本号
        App.version = device.version;
        // 手机平台 IOS / ANDROID
        App.platform = device.platform;

然后看一下www目录下的device.js

Device.prototype.getInfo = function(successCallback, errorCallback) {
    argscheck.checkArgs('fF', 'Device.getInfo', arguments);
    exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
};

cordova 插件最后都是通过exec函数完成插件调用的,在exec函数里,首先会判断平台,可能是如果是ios平台,cordova主要会通过iframe的方式与native交互。
cordova.exec往当前的html中插入一个不可见的iframe,从而向UIWebView请求加载一个特殊的URL,这个URL里当然就包含了要调用的native plugin的类名,方法名,参数,回调函数等信息。

   function iOSExec() {

        var successCallback, failCallback, service, action, actionArgs;
        var callbackId = null;
        if (typeof arguments[0] !== 'string') {

            successCallback = arguments[0];
            failCallback = arguments[1];
            service = arguments[2];
            action = arguments[3];
            actionArgs = arguments[4];

            callbackId = 'INVALID';
        } else {
            throw new Error('The old format of this exec call has been removed (deprecated since 2.1). Change to: ' +
            'cordova.exec(null, null, \'Service\', \'action\', [ arg1, arg2 ]);'
        );
        }

        actionArgs = actionArgs || [];

        if (successCallback || failCallback) {
            callbackId = service + cordova.callbackId++;
            cordova.callbacks[callbackId] =
                {success:successCallback, fail:failCallback};
        }

        actionArgs = massageArgsJsToNative(actionArgs);

        var command = [callbackId, service, action, actionArgs];

        commandQueue.push(JSON.stringify(command));

        if (!isInContextOfEvalJs && commandQueue.length == 1) {

            //Creates a gap bridge iframe used to notify the native code about queued
            if (execIframe && execIframe.contentWindow) {
            execIframe.contentWindow.location = 'gap://ready';
        } else {
            execIframe = document.createElement('iframe');
            execIframe.style.display = 'none';
            execIframe.src = 'gap://ready';
            document.body.appendChild(execIframe);
            }

            ...

        }
    }

native端通过UIWebView的方法,截获js端传来的命令。通过这个方式,js调用native是异步的。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest (NSURLRequest *)request navigationType: (UIWebViewNavigationType)navigationType

最后在看一下ios目录下CDVDevice文件
然后是CDVDevice.h文件,继承自CDVplugin类,调用getDeviceInfo获取设备信息,代码如下


#import <UIKit/UIKit.h> #import <Cordova/CDVPlugin.h> @interface CDVDevice : CDVPlugin {} + (NSString*)cordovaVersion; - (void)getDeviceInfo:(CDVInvokedUrlCommand*)command; @end

关于CDVInvokedUrlCommand
通过这个类的几个成员变量应该可以发现,使用这个类的实例来接收js端传过来的参数。

@interface CDVInvokedUrlCommand : NSObject {
    NSString* _callbackId;
    NSString* _className;
    NSString* _methodName;
    NSArray* _arguments;
}

到这里 js端使用cordova 插件的过程就完成了。

参考资料
http://cordova.apache.org/docs/en/latest/
http://www.cocoachina.com/industry/20140623/8919.html
http://www.jianshu.com/p/36f8fd15664c

未经允许,不得转载本站任何文章:代码山 » Cordova iOS平台的插件开发(一)

分享到:更多 ()

专注品牌化高端网站建设

商务服务联系我们