新建工程,添加Cordova 关键类

新建一个工程TestCordova 然后添加:confug.xml、Private 和 Public 两个文件夹里的所有文件

然后build 发现报错

为什么有会这么多报错呢?
原因是Cordova 部分类中,并没有#import <Foundation/Foundation.h>,但是它们却使用了这个库里的NSArray、NSString 等类型。
为什么用在终端里用命令行创建的工程就正常呢?
那是因为用命令行创建的工程里已经包含了pch 文件,并且已经import 了 Foundation框架。截图为证:

 
解决方案:创建一个pch文件,在pch文件里添加 #import <Foundation/Foundation.h> 
 
再次编译、运行,依然报错,WTF!
这里报错是因为Cordova的类引用错误,在命令行创建的工程里Cordova 是以子工程的形式加入到目标工程中,两个工程的命名空间不同,所以import 是用 类似这样的方式#import <Cordova/CDV.h>,但是我们现在是直接在目标工程里添加Cordova,所以要把#import <Cordova/CDV.h> 改为 #import "CDV.h"。其他的文件引用报错同理(比如:#import <Cordova/CDVCommandDelegate.h>会报错 只需改为 #import "CDVCommandDelegate.h"即可)。
 

设置控制器,添加WebView

1.加载本地HTML 
加载本地HTML,为了方便起见,首先新建一个叫www的文件夹,然后在文件夹里放入要加载的HTML和cordova.js
这里把www添加进工程时,需要注意勾选的是create foler references,创建的是蓝色文件夹:

 
配置插件映射,config.xml:
 <feature name="TestPlugin">
<param name="ios-package" value="TestPlugin" />
</feature>
<feature name="LocalStorage">
<param name="ios-package" value="CDVLocalStorage" />
</feature>
<feature name="HandleOpenUrl">
<param name="ios-package" value="CDVHandleOpenURL" />
<param name="onload" value="true" />
</feature>
<feature name="IntentAndNavigationFilter">
<param name="ios-package" value="CDVIntentAndNavigationFilter" />
<param name="onload" value="true" />
</feature>
<feature name="GestureHandler">
<param name="ios-package" value="CDVGestureHandler" />
<param name="onload" value="true" />
</feature>

下面我再截图看下:

OK,可以运行项目了:

 
 
 

2.加载远程HTML 
项目里一般都是这种情况,接口返回H5地址,然后用网页加载H5地址。
只需要设置下 self.startPage就好了。

这里有几个需要注意的地方:

1:self.startPage的赋值,必须在[super viewDidLoad]之前,否则self.startPage 会被默认赋值为index.html。
2:需要在config.xml中修改一下配置,否则加载远程H5时,会自动打开浏览器加载,
需要添加的配置是:
<allow-navigation href="https://*/*" />
<allow-navigation href="http://*/*" />
3:远程H5中也要引用cordova.js文件。
4:在 info.plist 中添加 App Transport Security Setting的设置。

创建插件,配置插件

在插件中实现JS要调用的原生方法,插件要继承自CDVPlugin,示例代码如下:

//
// TestPlugin.h
// TestCordova
//
// Created by Doman on 2017/7/14.
// Copyright © 2017年 Doman. All rights reserved.
// #import "CDV.h" @interface TestPlugin :CDVPlugin - (void)scan:(CDVInvokedUrlCommand *)command; - (void)location:(CDVInvokedUrlCommand *)command; - (void)pay:(CDVInvokedUrlCommand *)command; - (void)share:(CDVInvokedUrlCommand *)command; - (void)changeColor:(CDVInvokedUrlCommand *)command; - (void)testController:(CDVInvokedUrlCommand*)command; @end

配置插件,是在config.xml的widget中添加自己创建的插件,上面已经提到过。
如下图所示:

关于插件中方法的实现有几个注意点:
如果你发现类似如下的警告:

THREAD WARNING: ['scan'] took '290.006104' ms. Plugin should use a background thread.

那么直需要将实现改为如下方式即可:

[self.commandDelegate runInBackground:^{
// 这里是实现
}];

演示代码:

- (void)scan:(CDVInvokedUrlCommand *)command
{
[self.commandDelegate runInBackground:^{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"原生弹窗" message:nil delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil];
[alertView show];
});
}];
}

如何获取JS 传过来的参数呢?
CDVInvokedUrlCommand 参数,其实有四个属性,分别是argumentscallbackIdclassNamemethodName。其中arguments,就是参数数组。
看一个获取参数的示例代码:

- (void)share:(CDVInvokedUrlCommand *)command
{
NSUInteger code = ;
NSString *tip = @"分享成功";
NSArray *arguments = command.arguments;
if (arguments.count < ) {;
code = ;
tip = @"参数错误";
NSString *jsStr = [NSString stringWithFormat:@"shareResult('%@')",tip];
[self.commandDelegate evalJs:jsStr];
return;
} NSLog(@"从H5获取的分享参数:%@",arguments);
NSString *title = arguments[];
NSString *content = arguments[];
NSString *url = arguments[]; // 这里是分享的相关代码...... // 将分享结果返回给js
NSString *jsStr = [NSString stringWithFormat:@"shareResult('%@','%@','%@')",title,content,url];
[self.commandDelegate evalJs:jsStr];
}

如何将Native的结果回调给JS ?
这里有两种方式:第一种是直接执行JS,调用UIWebView 的执行js 方法。示例代码如下:

// 将分享结果返回给js
NSString *jsStr = [NSString stringWithFormat:@"shareResult('%@','%@','%@')",title,content,url];
[self.commandDelegate evalJs:jsStr];
第二种是,使用Cordova 封装好的对象CDVPluginResult和API。
使用这种方式时,在JS 调用原生功能时,必须设置执行成功的回调和执行失败的回调。即设置cordova.exec(successCallback, failCallback, service, action, actionArgs)的第一个参数和第二个参数。像这样:
function locationClick() {
cordova.exec(setLocation,locationError,"HaleyPlugin","location",[]);
}

然后,Native 调用JS 的示例代码:

- (void)location:(CDVInvokedUrlCommand *)command
{
// 获取定位信息...... // 下一行代码以后可以删除
// NSString *locationStr = @"广东省深圳市南山区学府路XXXX号";
NSString *locationStr = @"错误信息"; // NSString *jsStr = [NSString stringWithFormat:@"setLocation('%@')",locationStr];
// [self.commandDelegate evalJs:jsStr]; [self.commandDelegate runInBackground:^{
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:locationStr];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}];
}

上面大家已经看到,插件类要继承CDVPlugin ,点进去看下:

有个viewController,所以我门可以直接用.

演示代码:

- (void)testController:(CDVInvokedUrlCommand*)command
{ if (command.arguments.count>) {
//customize argument
TestViewController* testViewCtrl = [[TestViewController alloc]init];
[self.viewController presentViewController:testViewCtrl animated:YES completion:^{ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"我是OC回传的参数!"];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}];
}else{
//callback
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"没有参数"];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
} }

JS 要调用原生,执行的是:

// successCallback : 成功的回调方法
// failCallback : 失败的回调方法
// server : 所要请求的服务名字,就是插件类的名字
// action : 所要请求的服务具体操作,其实就是Native 的方法名,字符串。
// actionArgs : 请求操作所带的参数,这是个数组。
cordova.exec(successCallback, failCallback, service, action, actionArgs);

Native 调用 JS 方法

这个非常简单,如果是在控制器中,那么只需要像如下这样既可:

- (void)testClick
{ NSString *jsStr = @"asyncAlert('哈哈啊哈')";
[self.commandDelegate evalJs:jsStr]; }

这里的evalJs内部调用的其实是 UIWebView 的 stringByEvaluatingJavaScriptFromString方法。

OK。到这里就结束了。

demo地址: https://github.com/domanc/TestCordova.git

 
 
 

iOS下JS与OC互相调用(八)--Cordova简单实战的更多相关文章

  1. iOS下JS与OC互相调用(六)--WKWebView + WebViewJavascriptBridge

    上一篇文章介绍了UIWebView 如何通过WebViewJavascriptBridge 来实现JS 与OC 的互相调用,这一篇来介绍一下WKWebView 又是如何通过WebViewJavascr ...

  2. iOS下JS与OC互相调用(五)--UIWebView + WebViewJavascriptBridge

    WebViewJavascriptBridge是一个有点年代的JS与OC交互的库,使用该库的著名应用还挺多的,目前这个库有7000+star.我去翻看了它的第一版本已经是4年前了,在版本V4.1.4以 ...

  3. iOS下JS与OC互相调用(四)--JavaScriptCore

    前面讲完拦截URL的方式实现JS与OC互相调用,终于到JavaScriptCore了.它是从iOS7开始加入的,用 Objective-C 把 WebKit 的 JavaScript 引擎封装了一下, ...

  4. iOS下JS与OC互相调用(一)--UIWebView 拦截URL

    最近准备把之前用UIWebView实现的JS与原生相互调用功能,用WKWebView来替换.顺便搜索整理了一下JS 与OC 交互的方式,非常之多啊.目前我已知的JS 与 OC 交互的处理方式: * 1 ...

  5. iOS下JS与OC互相调用(二)--WKWebView 拦截URL

    在上篇文章中讲述了使用UIWebView拦截URL的方式来处理JS与OC交互. 由于UIWebView比较耗内存,性能上不太好,而苹果在iOS 8中推出了WKWebView. 同样的用WKWebVie ...

  6. iOS下JS与OC互相调用(八)--Cordova详解+实战

    扯两句,可以跳过 由于项目中Cordova相关功能一直是同事在负责,所以也没有仔细的去探究Cordova到底是怎么使用的,又是如何实现JS 与 OC 的交互.所以我基本上是从零开始研究和学习Cordo ...

  7. iOS下JS与OC互相调用

    背景情况: app项目中有几个界面是需要经常变动的(不仅是内容还有UI布局等),比如活动宣传界面就是属于这一类.但是由于AppStore提交审核也是需要时间的,就算审核快,也不至于每次都为了这点事频繁 ...

  8. iOS下JS与OC互相调用(七)--Cordova 基础

    Cordova 简介 在介绍Cordova之前,必须先提一下PhoneGap.PhoneGap 是Nitobi软件公司2008年推出的一个框架,旨在弥补web 和iOS 之间的不足,使得web 和 i ...

  9. iOS下JS与OC互相调用(三)--MessageHandler

    使用WKWebView的时候,如果想要实现JS调用OC方法,除了拦截URL之外,还有一种简单的方式.那就是利用WKWebView的新特性MessageHandler来实现JS调用原生方法. Messa ...

随机推荐

  1. HSSF NPOI 颜色

    using System; using System.IO; using System.Windows.Forms; using NPOI.HSSF.UserModel; using NPOI.SS. ...

  2. IE下的Firebug——IE WebDeveloper js debug

    原文地址:http://blog.csdn.net/wangbin1986/article/details/6837285 对于大部分做前端设计者而言应该都使用过Firefox浏览器下一款调试网站的扩 ...

  3. Shell 定时发送邮件检查网站脚本/邮件正文

    #!/bin/bash ############################################################## # File Name: check_http.s ...

  4. 1035 Password (20 分)

    1035 Password (20 分) To prepare for PAT, the judge sometimes has to generate random passwords for th ...

  5. RNN总结

    RNN既可以表述为循环神 经网络(recurrent neural network),也可以表述为递归神经网络(recursive neural network),前者一般用于处理以时间序列为输入的问 ...

  6. Vue 路由配置、动态路由

    1.安装 npm install vue-router --save / cnpm install vue-router --save 2.引入并 Vue.use(VueRouter) (main.j ...

  7. Axure8.1.0.3372 注册码

    Axure8.1.0.3372 注册码 转载:http://blog.csdn.net/cslucifer/article/details/79355007 Koshy wTADPqxn3KChzJx ...

  8. openstack 基镜像与差异镜像的整合

  9. ftps加密服务器

    咱不废话,理论不提,直接上步骤,[linux下的ftps服务器系统搭建步骤如下,按此步骤,即可搭建ftps服务器系统] 1.[安装vsftpd] yum -y install vsftpd 2.[安装 ...

  10. JAVA 常用注解( JDK, Spring, AspectJ )

    JDK自带注解   @Override   表示当前方法覆盖了父类的方法   @Deprecation   表示方法已经过时,方法上有横线,使用时会有警告   @SuppviseWarnings    ...