Cordova详解2
来源:互联网 发布:网络电视包月怎么取消 编辑:程序博客网 时间:2024/06/06 23:51
版权声明:本文为博主原创文章,转载请注明出处。
目录(?)[+]
扯两句,可以跳过
由于项目中Cordova相关功能一直是同事在负责,所以也没有仔细的去探究Cordova到底是怎么使用的,又是如何实现JS 与 OC 的交互。所以我基本上是从零开始研究和学习Cordova的使用,从上篇在官网实现命令行创建工程,到工程运行起来,实际项目中怎么使用Cordova,可能还有一些人并不懂,其实我当时执行完那些命令后也不懂。
后来搜索了一下关于Cordova 讲解的文章,没有找到一篇清晰将出如何使用Cordova,大多都是讲如何将Cordova.xcodeproj拖进工程等等。我不喜欢工程里多余的东西太多,其实并不需要将Cordova 整个工程拖进去,只需要一部分就够了,下面我会一一道来。
1.新建工程,添加Cordova 关键类
我这里用Xcode 8 新建了一个工程,叫 JS_OC_Cordova
,然后将Cordova关键类添加进工程。
有哪些关键类呢?
这里添加config.xml
、Private
和 Public
两个文件夹里的所有文件。工程目录结构如下:
然后运行工程,�� �� �� ,你会发现报了一堆的错误:
为什么有会这么多报错呢?
原因是Cordova 部分类中,并没有#import <Foundation/Foundation.h>
,但是它们却使用了这个库里的NSArray、NSString 等类型。
为什么用在终端里用命令行创建的工程就正常呢?
那是因为用命令行创建的工程里已经包含了pch 文件,并且已经import 了 Foundation框架。截图为证:
其实这里有两种解决方案:1、在报错的类里添加上 #import <Foundation/Foundation.h>
;2、添加一个pch 文件,在pch文件里加上 #import <Foundation/Foundation.h>
。
我选择第二种方案:
再次编译、运行,依然报错。 What the fuck �� �� �� !!!
不用急,这里报错是因为Cordova的类引用错误,在命令行创建的工程里Cordova 是以子工程的形式加入到目标工程中,两个工程的命名空间不同,所以import 是用 类似这样的方式#import <Cordova/CDV.h>
,但是我们现在是直接在目标工程里添加Cordova,所以要把#import <Cordova/CDV.h>
改为 #import "CDV.h"
。其他的文件引用报错同理。
当然,如果想偷懒,也可以从后面我给的示例工程里拷贝,我修改过的Cordova库。
2.设置网页控制器,添加网页
首先将 ViewController
的父类改为 CDVViewController
。如下图所示:
这里分两种情况,加载本地HTML 和远程HTML 地址。
* 加载本地HTML *
加载本地HTML,为了方便起见,首先新建一个叫www
的文件夹,然后在文件夹里放入要加载的HTML和cordova.js
。
这里把www
添加进工程时,需要注意勾选的是create foler references,创建的是蓝色文件夹。
最终的目录结构如下:
上面为什么说是方便起见呢?
先说答案,因为CDVViewController
有两个属性 wwwFolderName
和 startPage
, wwwFolderName
的默认值为www
,startPage
的默认值为 index.html
。
在 CDVViewController
的 viewDidLoad
方法中,调用了与网页相关的三个方法: - loadSetting
、- createGapView
、- appUrl
。
先看- loadSetting
,这里会对 wwwFolderName
和 startPage
设置默认值,代码如下:
- 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
要看- createGapView
,是因为这个方法内部先调用了一次 - appUrl
,所以关键还是- appUrl
。源码如下:
- 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
此时运行效果图:
* 加载远程HTML *
项目里一般都是这种情况,接口返回H5地址,然后用网页加载H5地址。
只需要设置下 self.startPage
就好了。
这里有几个需要注意的地方:
1.self.startPage
的赋值,必须在[super viewDidLoad]之前,否则self.startPage 会被默认赋值为index.html。
2. 需要在config.xml
中修改一下配置,否则加载远程H5时,会自动打开浏览器加载。
需要添加的配置是:
- 1
- 2
- 远程H5中也要引用
cordova.js
文件。 - 在
info.plist
中添加App Transport Security Setting
的设置。
运行效果图:
3.创建插件,配置插件
在插件中实现JS要调用的原生方法,插件要继承自CDVPlugin
,示例代码如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
配置插件,是在config.xml的widget
中添加自己创建的插件。
如下图所示:
关于插件中方法的实现有几个注意点:
1、如果你发现类似如下的警告:
- 1
那么直需要将实现改为如下方式即可:
- 1
- 2
- 3
示例代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
2、如何获取JS 传过来的参数呢? CDVInvokedUrlCommand
参数,其实有四个属性,分别是arguments
、callbackId
、className
、methodName
。其中arguments
,就是参数数组。
看一个获取参数的示例代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
3、如何将Native的结果回调给JS ?
这里有两种方式:第一种是直接执行JS,调用UIWebView 的执行js 方法。示例代码如下:
- 1
- 2
- 3
第二种是,使用Cordova 封装好的对象CDVPluginResult
和API。
示例代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
4.JS 调用Native 功能
终于到重点了,JS想要调用原生代码,如何操作呢?我用本地HTML 来演示。
首先,HTML中需要加载 cordova.js
,需要注意该js 文件的路径,因为我的cordova.js
与HTML放在同一个文件夹,所以src 是这样写:
- 1
然后,在HTML中创建几个按钮,以及实现按钮的点击事件,示例代码如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
点击事件对应的关键的JS代码示例:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
JS 要调用原生,执行的是:
- 1
- 2
- 3
- 4
- 5
- 6
cordova,是cordova.js
里定义的一个 var
结构体,里面有一些方法以及其他变量,关于exec ,可以看 iOSExec这个js 方法。
大致思想就是,在JS中定义一个数组和一个字典(键值对)。
数组中存放的就是:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
callbackId = service + cordova.callbackId++;
cordova.callbacks[callbackId] =
{success:successCallback, fail:failCallback};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
function pokeNative() {
// CB-5488 - Don’t attempt to create iframe before document.body is available.
if (!document.body) {
setTimeout(pokeNative);
return;
}
// Check if they’ve removed it from the DOM, and put it back if so.
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);
}
failSafeTimerId = setTimeout(function() {
if (commandQueue.length) {
// CB-10106 - flush the queue on bridge change
if (!handleBridgeChange()) {
pokeNative();
}
}
}, 50); // Making this > 0 improves performance (marginally) in the normal case (where it doesn’t fire).
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
if ([[url scheme] isEqualToString:@”gap”]) {
[vc.commandQueue fetchCommandsFromJs];
// The delegate is called asynchronously in this case, so we don’t have to use
// flushCommandQueueWithDelayedJs (setTimeout(0)) as we do with hash changes.
[vc.commandQueue executePending];
return NO;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- (void)testClick
{
// 方式一:
NSString *jsStr = @”asyncAlert(‘哈哈啊哈’)”;
[self.commandDelegate evalJs:jsStr];
}``
evalJs
这里的内部调用的其实是
UIWebView的
stringByEvaluatingJavaScriptFromString` 方法。
6.如果你在使用Xcode 8时,觉得控制台里大量的打印很碍眼,可以这样设置来去掉。
首先:
然后,添加一个环境变量:
好了,到这里关于Cordova 的讲解就结束了。
示例工程的github地址:JS_OC_Cordova
Have Fun!
- Cordova详解2
- Cordova android框架详解
- Cordova android框架详解
- cordova 命令详解
- cordova详解及介绍
- Cordova android框架详解
- Cordova android框架详解
- Cordova android框架详解
- Cordova android框架详解
- Cordova 插件详解
- Cordova android框架详解
- cordova详解1
- Cordova-----2、创建Cordova项目
- Cordova
- cordova
- Cordova
- Cordova
- cordova
- C语言,进制转换之十进制转二进制,完整代码
- HDU 6137 Engineering of the Clones(快速幂+NTT)
- c0201时遇到的问题
- Android 开发规范
- vmware 合并块和迁移
- Cordova详解2
- 初识JavaScript,Ajax,jQuery,并比较三者关系
- `html语言基础笔记
- bzoj1095: [ZJOI2007]Hide 捉迷藏(动态点分治+树上ST表)
- 搞了好几天,终于搞好了hadoop环境安装!
- [Java] 组合与继承的区别
- win10家庭版关闭windows defender
- 枚举(enum)用法总结
- SprintBoot学习笔记(3):简单登录功能