Cordova是一个开源的移动开发框架,它允许你使用WEB开发技术(HTML5、CSS3、JavaScript)进行跨平台开发,可以在每个平台的封装器中执行,并且依赖规范的API对设备进行高效的访问,比如传感器、数据、网络状态等等。Cordova可以让JS与原生代码互相通信的一个库,并且提供了一组设备相关的API,通过这组API,移动应用能够以JavaScript访问原生的设备功能,如摄像头、麦克风等。这些API插件类都是基于JS与Objective-C可以互相通信的基础的。
Cordova支持iOS, Android等系统。
常见的使用场景:
前段时间在公司项目中使用了Cordova来配合EF同事做H5的交互,用起来比网络请求的交互方便很多,今天来简单的分享一下使用方式。
2.安装好Node.js之后,我们就能使用npm命令来安装Cordova了
打开终端,输入以下命令:
sudo npm install -g cordova
过程中会有提示你输入密码,和输入yes,直接按照过程通过就行。
3.安装完成之后,开始创建
3.1使用命令行工具创建一个空白的Cordova项目,cd到创建项目的目录,输入以下代码:
sudo cordova create YourApp
如果有不确定和不知道的情况,可以使用以下代码进行查看:
cordova help create
3.2切换到YourApp目录,并修改指定平台,代码如下:
cd YourApp
sudo cordova platform add ios
3.3让这个配置好的demo项目跑起来:
cordova run ios
当以上步骤都完成了,我们就使用Find打开YourApp的文件夹,查看内部文件,大概样子如下:
然后我们打开platforms文件夹里面ios文件夹,就会看到Cordova的demo项目,如图:
Cordova配置到这里就结束啦,如果有兴趣可以直接打开看一下文件结构以及方法调用等信息。
现在我们开始在项目中接入Cordova,先打开Xcode创建一个名为test的空项目。然后看上面的图片可以看到demo文件夹中的文件,我们需要直接拿到我们的项目中,具体的文件如图:
当文件都拷贝到我们的项目(这里使用test项目)中,test项目文件目录如下:
打开工程从目录中移除文件夹cordova、CordovaLib(不是移除到废纸篓,只是删除目录),然后导入CordovaLib文件夹中的CordovaLib.xcodeproj,然后test项目结构就成了如图所示:
接下来我们继续配置,在target里面选中test,进入到Build Phases中,添加文件,如图:
并在这里创建一个新的项 New Run Script Phases,名为copy www directory,然后在配置项里面复制粘贴如下代码:
NODEJS_PATH=/usr/local/bin; NVM_NODE_PATH=~/.nvm/versions/node/`nvm version 2>/dev/null`/bin; N_NODE_PATH=`find /usr/local/n/versions/node/* -maxdepth 0 -type d 2>/dev/null | tail -1`/bin; XCODE_NODE_PATH=`xcode-select --print-path`/usr/share/xcs/Node/bin; PATH=$NODEJS_PATH:$NVM_NODE_PATH:$N_NODE_PATH:$XCODE_NODE_PATH:$PATH && node cordova/lib/copy-www-build-step.js
配置如图:
在工程的 Build Settings中找到 Linking,包含项Other Linker Flags中添加-ObjC、-all_load,如图:
这样Cordova就接入好我们的test项目了,接下来就是让它跑起来,打开test项目的ViewController.h文件,导入CD头文件,把ViewController 继承自CDVViewController,如图所示:
然后就 cmd + r 运行项目,效果如图:
运行的程序看到的网页信息,是就工程中wwww文件目录下的index.html文件。如果公司是本地网页,那我们可以对index.html文件进行定制,以及拓展,直接成为webApp,不过一般需求,都是远端网页和原生交互,那么问题来了,Cordova怎么打开远端网页呢?
首先在项目的info.plist里面添加字段 App Transport Security Settings,在子字段里面添加Allow Arbitrary Loads 设置为BOOL类型,赋值为YES,如图:
打开我们的config.xml文件,在allow-intent href="https://* / *下面添加如下代码:
<allow-navigation href="https://*/*" />
<allow-navigation href="http://*/*" />
配置如图:
然后在我们的ViewController.m文件里面实现如下代码:
有人会问了,为什么我们不在viewdidload里面写呢?可以按住cmd点开CDVViewController追踪,发现父类的viewdidload调用了与网页相关的方法:loadSetting。而在loadSetting方法中,我们看到这里会对folder和page设置默认值,Cordova源代码如下:
- (void)loadSettings
{
CDVConfigParser* delegate = [[CDVConfigParser alloc] init];
[self parseSettingsWithParser:delegate];
// Get the plugin dictionary, whitelist and settings from the delegate.
self.pluginsMap = delegate.pluginsDict;
self.startupPluginNames = delegate.startupPluginNames;
self.settings = delegate.settings;
// And the start folder/page.
if(self.wwwFolderName == nil){
self.wwwFolderName = @"www";
}
if(delegate.startPage && self.startPage == nil){
self.startPage = delegate.startPage;
}
if (self.startPage == nil) {
self.startPage = @"index.html";
}
// Initialize the plugin objects dict.
self.pluginObjects = [[NSMutableDictionary alloc] initWithCapacity:20];
}
所以我们需要在父类的viewdidload调用之前,让page和folder赋值,不过,现在我们已经不需要再使用这么麻烦的了。就像之前给大家看的图片一样,我们现在只需要使用如下代码:
NSURLRequest * rq = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]];
// 跳转外部网页
[self.webViewEngine loadRequest:rq];
在viewwillappear里面执行,就可以跳转外部网页了。我在这里跳转了我的个人主页,如图:
到这里,Cordova就已经集成进入我们的项目了,但大家是不是还发现少了些什么呢?交互,是的,现在我们能拿到外部网页了,我们就该和前端的同学们做交互了,接下来继续了解一下Cordova的交互。
简介:插件是Cordova生态系统的核心部分,它们提供了一个Cordova和本地组件交互的接口和绑定标准设备的API。这能让你通过JavaScript调用本地代码,Cordova项目包含一系列叫做核心插件的插件集合。这些核心的插件能让你的应用高效的访问设备,比如电池、摄像头、联系人等等.除了这些核心的插件之外,这些还有一些提供在所有平台上不必要的额外特征的第三方插件。可以通过插件搜索或npm进行查找Cordova插件。也可以开发你自己的插件,比如,插件可以实现自定义本地组件和Cordova的交互。
文章开头我们也介绍了常见的使用场景:
我们来开发一个最简单的插件,点击网页按钮调用本地弹窗提示:
1.首先我们来新建一个文件,文件继承自CDVPlugin,如图:
2.会有报错,把import修改为Cordova/CDVPlugin.h,如图:
3.在config.xml文件中,写入我们的插件代码如下:
<feature name="MyTestPlugin">
<param name="ios-package" value="MyTestPlugin" />
<param name="onload" value="true" />
feature>
配置如图:
4.然后修改index.html文件,原件如下:
<html>
<head>
<meta charset="utf-8" />
<title>title>
<script type="text/javascript" src="cordova.js">script>
<script type="text/javascript" src="cordova_plugins.js">script>
<script type="text/javascript" src="jquery.min.js">script>
<script type="text/javascript">
document.addEventListener("deviceready", yourCallbackFunction, false);
// 自己定义的button点击事件
// Cordova.exec后三个绑定插件的参数分别是:插件名、插件方法、传输内容
function BTClick(){
Cordova.exec(successFunction, failFunction, "MyTestPlugin", "testMethod", ["弹出alertView"]);
}
// 失败回调
function failFunction(error){
alert(error);
}
// 成功回调
function successFunction(ok){
alert(ok);
}
script>
head>
<body>
<p>点击下面按钮弹出alertViewp>
<button onclick="BTClick()">弹出alertViewbutton>
body>
html>
5.在自定义插件里面添加常用拦截方式,testMethod:(CDVInvokedUrlCommand *)cmd,在.m文件中实现一下,代码如下:
- (void)testMethod:(CDVInvokedUrlCommand *)cmd{
if ([[cmd.arguments objectAtIndex:0]isEqualToString:@"弹出alertView"]) {
// 打开弹窗
UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"点击网页按钮弹出提示" delegate:nil cancelButtonTitle:@"好的" otherButtonTitles:nil, nil];
[alert show];
}
}
演示效果如下:
这样我们的插件就完成了,有兴趣的同学可以去拓展一下~
如果有小伙伴不理解我自定义的方法 testMethod:(CDVInvokedUrlCommand *)cmd 怎么就能获取网页的返回值的,可以去Cordova的官网查看iOS查件制作教程哟。
好啦我们接着往下看,在这里我分享一段带注释的代码,也是刚才在5步骤的代码拓展的:
- (void)testMethod:(CDVInvokedUrlCommand *)cmd{
/*
cmd所带回来的信息:
callbackId 回调时的命令id
className 回调的类名
methodName 回调的方法名
arguments 回调的参数
*/
// 该方法使用后台线程,避免阻塞,也可以把里面的方法写出到外面来
[self.commandDelegate runInBackground:^{
// 一般根据cmd的arguments(存储为字符串)来判断我们想要实现的方法
NSLog(@"%@",cmd.arguments);
/**
比如:
if ([[cmd.arguments objectAtIndex:0]isEqualToString:@"设置页面title"]) {
// 设置title
}
if ([[cmd.arguments objectAtIndex:0]isEqualToString:@"跳转页面"]) {
// 跳转页面
}
if ([[cmd.arguments objectAtIndex:0]isEqualToString:@"记录某个值"]) {
// 记录值
}
*/
/**
一般交互,我们只是根据H5的点击事件来完成本地操作,如果需要交互,返回数据就用以下方法:
pluginResult 返回数据
CDVCommandStatus 状态
__block CDVPluginResult* pluginResult = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"App反馈给网页的字符串"];
[self.commandDelegate sendPluginResult:pluginResult callbackId:cmd.callbackId];
*/
}];
}
使用Cordova做交互的时候,插件会自动返回交互信息,这个cmd里面包含有四个参数:
属性 | 作用 |
---|---|
callbackId | 回调时的命令id |
className | 回调的类名 |
methodName | 回调的方法名 |
arguments | 回调的参数 |
我们一般常用的就是回调的参数arguments,一般根据项目需求来决定怎么使用和拓展。
大家可以看看上面的代码,有很多注释,包括一个返回交互,里面可以设置Cordova的返回信息,比如我们本地收到网页的交互通知了,我们在原生的App中做完事务之后,要返回给网页一个状态,或者信息,这时候我们就需要使用sendPluginResult方法来完成。
1.首先我们来修改index.html文件的方法,让网页收到CDVCommandStatus_OK状态的时候,把我们从App传到网页的信息展示出来,在插件部分的4步骤中,index.html已经写好了成功的回调,代码如下:
function successFunction(ok){
alert(ok);
}
2.我们来修改插件的方法,在点击“弹出alertView”按钮的时候,把在插件部分的5步骤中的alertView代码去掉,使用如下代码:
__block CDVPluginResult* pluginResult = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"上传给网页的字符串"];
[self.commandDelegate sendPluginResult:pluginResult callbackId:cmd.callbackId];
网页的弹窗运行效果如下:
我们可以看到,网页JS的alert弹窗出现了。
至此,一个最简单的插件和最简单的交互就完成了。