1. 程式人生 > >cordova iOS平臺的外掛開發

cordova iOS平臺的外掛開發

2016-06-13  閱讀(425) 評論(33) 

我們先看一下cordova外掛的資料夾,都包括哪些目錄以及檔案。這裡我以Device外掛為例:

外掛目錄

Device外掛目錄結構

因為是官方的外掛所以目錄和檔案比較多,我們在實際開發中可以適當的增刪,不過有些是必須要有的。

src

目錄裡面放對應不同平臺的檔案,andorid是java,iOS是.h和.m檔案

www

資料夾下放我們的javascript檔案。

plugin.xml

外掛的配置檔案。

plugin.xml

<pluginxmlns="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-modulesrc="www/device.js"name="device"><clobberstarget="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
<platformname="ios"><config-filetarget="config.xml"parent="/*"><featurename="Device"><paramname="ios-package"value="CDVDevice"/></feature></config-file><header-filesrc="src/ios/CDVDevice.h"/><source-filesrc="src/ios/CDVDevice.m"/></platform>

這裡是外掛的配置資訊(iOS為例子)的外掛資訊插入到平臺的 config.xml 檔案中,來通知平臺添加了外掛.

外掛的呼叫過程

要開發自己的cordova外掛,瞭解一下外掛的呼叫過程是非常有必要的。下面是簡單介紹一下。

首先我們在js中呼叫device的方法,獲取裝置資訊。

App.uuid = device.uuid;// 裝置的模型或產品的名稱App.model = device.model;// 系統版本號App.version= device.version;// 手機平臺 IOS / ANDROIDApp.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{thrownewError('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 queuedif(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>@interfaceCDVDevice:CDVPlugin{}+(NSString*)cordovaVersion;-(void)getDeviceInfo:(CDVInvokedUrlCommand*)command;@end

關於CDVInvokedUrlCommand
通過這個類的幾個成員變數應該可以發現,使用這個類的例項來接收js端傳過來的引數。

@interfaceCDVInvokedUrlCommand: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