一:关于Cordoval理论知识javascript
1:PhoneGap是手机平台上流行的一款中间件。它构建在各类手机平台所提供的WebView(浏览器内核)组件的基础之上,使用javascript语言对应用开发者提供统一的接口(如调用相机、调用其余本地组件),从而屏蔽了各手机平台上OS的异构。在无线小组的调研任务中,个人任务主要是负责iOS平台上的调研,本文简单描述了iOS平台上PhoneGap与平台本地的互操做性的实现。 html
2:PhoneGap由于被捐赠给了Apache而更名为Cordova,因此PhoneGap里的类名都以CDV做为前缀。在iOS平台上,最重要的一个核心类是CDVViewController。该类直接继承自UIViewController,于是具有了全部UIViewController所具有的特性。同时,该类还实现了两个Protocol(即接口):UIWebViewDelegate和CDVCommandDelegate。所以它也负责UIWebView的一些callback,以及CDVInvokedUrlCommand的执行。java
3:CDVViewController类的主要对象成员是CDVCordovaView *webView,在源代码中能够看出,这个webView对象是CDVViewController的self.view上的惟一被add进来的子对象,即负责了整个CDVViewController类的显示。而CDVCordovaView类则没什么特别的,它直接继承自UIWebView。ios
4:当CDVViewController在构建时,它有两个很重要的属性:NSString*wwwFolderName和NSString *startPage。这两个属性值使得CDVViewController在load以后直接加载wwwFolderName下的startPage做为初始显示的页面。git
以上是对CDVViewController的一个简单介绍。容易明白的是,在iOS应用中使用了CDVViewController以后,界面实际上就彻底交给了CDVCordovaView*webView,即一个UIWebView。github
二:使用Cordoval常碰到的问题web
config.xml 是一个用来配置应用的全局属性的文件, 在此文件中配置的属性应该是能适应全部平台的. 在编译的时候配置文件将会被编译到对应的平台中.数组
1:如何在Cordoval加载远程的URL网址xcode
在Config.xml配置文件时增长下面两个,即可以打开URL的HTML页面浏览器
<allow-navigation href="http://*/*" /> <allow-navigation href="https://*/*" />
2:在Cordoval中加载同一个域的URL是在APP打开,跳转到其它倒是用safari浏览器打开
一样是在Config.xml配置中把下面两个删除,这样它便会一直在APP里面进行跳转
<!-- <allow-intent href="http://*/*" />--> <!-- <allow-intent href="https://*/*" />-->
2.1:禁用 WebViewBounce
UIWebView是iOS SDK中一个最经常使用的控件, 在Cordova中, 默认也是使用UIWebView做为默认视图显示咱们的HTML应用的.
在使用Cordova的项目中, 默认WebViewBounce这个选项是打开的, 因此使用手指向下或者向上滑动屏幕时, 常常会看到页面底部和屏幕底部会出现一大片空白, 而后松开手指后, 再弹回去的特效.
<preference name="WebViewBounce" value="false" /> <preference name="DisallowOverscroll" value="true" />
2.2:config.xml access配置
只容许google.com Access to google.com:
<access origin="http://google.com" />
只容许google.com的https协议 Access to the secure google.com (https://):
<access origin="https://google.com" />
二级域名(maps) Access to the subdomain maps.google.com:
<access origin="http://maps.google.com" />
全部二级域名 Access to all the subdomains on google.com, for example mail.google.com and docs.google.com:
<access origin="http://*.google.com" />
全部域名 Access to all domains, for example, google.com and developer.mozilla.org:
<access origin="*" />
2.3:config.xml Navigation Whitelist
说明:webview能够跳转至的URL
<!-- 容许全部到example.com的连接 --> <!-- Allow links to example.com --> <allow-navigation href="http://example.com/*" /> <!-- 通配符 --> <!-- Wildcards are allowed for the protocol, as a prefix to the host, or as a suffix to the path --> <allow-navigation href="*://*.example.com/*" /> <!-- 通配符(全) *不推荐* --> <!-- A wildcard can be used to whitelist the entire network, over HTTP and HTTPS. *NOT RECOMMENDED* --> <allow-navigation href="*" /> <!-- 上面的写法与下面3句等价 --> <!-- The above is equivalent to these three declarations --> <allow-navigation href="http://*/*" /> <allow-navigation href="https://*/*" /> <allow-navigation href="data:*" />
2.4:config.xml Intent Whitelist
说明:系统能够打开的连接
<!-- Allow links to web pages to open in a browser --> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <!-- Allow links to example.com to open in a browser --> <allow-intent href="http://example.com/*" /> <!-- Wildcards are allowed for the protocol, as a prefix to the host, or as a suffix to the path --> <allow-intent href="*://*.example.com/*" /> <!-- Allow SMS links to open messaging app --> <allow-intent href="sms:*" /> <!-- Allow tel: links to open the dialer --> <allow-intent href="tel:*" /> <!-- Allow geo: links to open maps --> <allow-intent href="geo:*" /> <!-- Allow all unrecognized URLs to open installed apps *NOT RECOMMENDED* --> <allow-intent href="*" />
2.5:config.xml Network Request Whitelist
说明:网络请求(如XHR等)白名单
<!-- Allow images, xhrs, etc. to google.com --> <access origin="http://google.com" /> <access origin="https://google.com" /> <!-- Access to the subdomain maps.google.com --> <access origin="http://maps.google.com" /> <!-- Access to all the subdomains on google.com --> <access origin="http://*.google.com" /> <!-- Enable requests to content: URLs --> <access origin="content:///*" /> <!-- Don't block any requests --> <access origin="*" />
2.6:index.html Content Security Policy
说明:页面上的资源白名单
主要分这几类:default-src,style-src,script-src,img-src,font-src,media-src 等
参数值能够是:*,'self','unsafe-inline',data: 等
我使用的是很是宽松的策略:
容许全部域名的数据,容许不安全的内联,容许data:(主要用于BASE64形式的图片,字体等)
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline';img-src * 'self' data:;font-src 'self' data:">
3:如何加载不一样的启动页URL地址
在配置Config.xml文件中有个content的节点,里面默认是有一个打开本地的地址index.html(好比:<content src="index.html" />); 这个就是跳转到本地包里面的html页面,也能够修改为(好比:<content src="https://www.baidu.com/" />);
上面这种只是修改默认的地址,可能不符合对于项目实际用法,项目中要加载Cordova都会有一个viewController的控制器继承于CDVViewController,它时就有一个属性startPage用于设置跳到webView加载的html页面;其中使用CDVViewController一般须要设置wwwFolderName的目录名称,和startPage首页的名称便可。默认wwwFolderName为www,startPage默认为index.html;这个也是模板直接生成时文件的名称;
self.viewController.startPage=@"http://www.cnblogs.com";
4:如何加载HTML页面存放在盒沙中
self.viewController = [[MainViewController alloc] init]; NSString *curFilePath=[NSString stringWithFormat:@"file://%@/www",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]]; NSLog(@"路径为:%@",curFilePath); if ([[NSFileManager defaultManager] fileExistsAtPath:curFilePath]) { self.viewController.wwwFolderName = curFilePath; } self.viewController.startPage=@"index.html";
一样是在wwwFolderName上作文章,由于它是前缀文件夹的路径,这边要注意是关于路径要运用file://方式进行读取;
由于能够读取沙盒里面的HTML页面,这样咱们就能够更加灵活运用,好比HTML经过服务端去下载到沙盒解压,这样就能够作到动态修改;
5:加载页面跟结束加载页面的监听,有两个通知能够监听,用来处理等待效果展示
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(onNotification:) name:CDVPluginResetNotification // 开始加载 object:nil]; [center addObserver:self selector:@selector(onNotificationed:) name:CDVPageDidLoadNotification // 加载完成 object:nil]; } - (void)onNotification:(NSNotification *)text{ NSLog(@"-----开始等待------"); } - (void)onNotificationed:(NSNotification *)text{ NSLog(@"-----结束等待------"); }
6:刷新UIWebView,UIWebView直接更改url并reload是没有用的。必须声明一个NSURLRequest,并从新loadRequest。刷新时的url必须是符合Cordova规则的url。在Cordova源码中有一个appUrl的方法,经过这个方法转出的url才能被CDVViewController正常加载;
localWebVC.wwwFolderName = @"www"; localWebVC.startPage = @"local.html"; NSURL *url = [self.localWebVC performSelector:@selector(appUrl)]; if (url) { NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; [self.localWebVC.webView loadRequest:request]; }
7:使用pod管理Cordoval及其插件(IOS8以上才可使用到最新版本)
pod 'Cordova'
若是须要引入一些相关的插件,能够加入以下配置,下面的这些插件能够经过pod搜索到:
pod 'CordovaPlugin-console' pod 'cordova-plugin-camera' pod 'cordova-plugin-contacts' pod 'cordova-plugin-device' pod 'cordova-plugin-device-orientation' pod 'cordova-plugin-device-motion' pod 'cordova-plugin-globalization' pod 'cordova-plugin-geolocation' pod 'cordova-plugin-file' pod 'cordova-plugin-media-capture' pod 'cordova-plugin-network-information' pod 'cordova-plugin-splashscreen' pod 'cordova-plugin-inappbrowser' pod 'cordova-plugin-file-transfer' pod 'cordova-plugin-statusbar' pod 'cordova-plugin-vibration'
注意:若是没有用pod来管理Cordova,默认工程都会有一个CordovaLib.xcodeproj来把Cordova的类引入,因此建议Cordova用pod引入,就能够调用,而关于html、JS等静态模板仍是在工程中;能够查看下面两个网址
iOS中Cordova开发初探 地址:http://blog.devzeng.com/blog/hello-cordova-ios.html
Cordova使用Pod实例 地址:https://github.com/phonegap/phonegap-webview-ios 【POD引入的模块都存在】
三:插件内容
对于Cordova在插件上面仍是比较多,也能够自定义插件的开发,对于插件下面已经有列出一些,其它插件能够上Cordova或者gitHub进行查找;
支付宝支付插件: iOS/Android 地址:https://github.com/fami2u/cordova-plugin-alipay.git 微信支付插件: iOS/Android 地址:https://github.com/fami2u/cordova-plugin-weipay.git ping++支付插件: iOS 地址:https://github.com/fami2u/cordova-ping-fami.git 扫描二维码和条形码插件: iOS/Android 地址:https://github.com/fami2u/cordova-barcodescanner-fami.git 拍照插件: iOS/Android 地址:https://github.com/fami2u/cordova-plugin-camera.git 极光推送插件: iOS/Android 地址:https://github.com/fami2u/jpush-phonegap-plugin.git iOS 地址:https://github.com/fami2u/cordova-Jpush-fami.git 第三方登陆插件: iOS 地址:https://github.com/fami2u/cordova-UMLogin-fami.git JS 地址:https://github.com/fami2u/cordova-plugin-wechat.git 第三方分享插件: iOS 地址:https://github.com/fami2u/cordova-UMShare-fami.git 跳转地图插件: iOS 地址:https://github.com/fami2u/cordova-plugin-map.git 视频播放插件: iOS 地址:https://github.com/fami2u/cordova-player-fami.git
四:有可能出现的问题
1:在使用cordova6.0的过程当中,编译好的APP运行在IOS7+系统上默认是与状态栏重叠的,而运行在IOS6及老版本中时是于状态栏分离的。
解决办法:把文件MainViewController.m中的方法viewWillAppear进行相关修改以下。 做用是更改view的边界,使其下移20px,恰好是状态栏的高度。
- (void)viewWillAppear:(BOOL)animated { if([[[UIDevice currentDevice]systemVersion ] floatValue]>=7) { CGRect viewBounds=[self.webView bounds]; viewBounds.origin.y=20; viewBounds.size.height=viewBounds.size.height-20; self.webView.frame=viewBounds; } [super viewWillAppear:animated]; }
2:在html页面内调用系统相机之后再返回,整个页面底部会有白色的空白控件,用调试工具查看后空白区域的高度是20px.该如何解决?
解决办法:因为整个cordova项目至关于一个页面的应用,不一样的模块汇集在一块儿,因此当当前屏幕消失后(好比进入系统相机拍照页面)再出现的时候,仍是会执行上面的代码,因此界面高度再次减小20px.
-(void)viewWillDisappear:(BOOL)animated { if([[[UIDevice currentDevice]systemVersion ] floatValue]>=7) { CGRect viewBounds=[self.webView bounds]; viewBounds.origin.y=20; viewBounds.size.height=viewBounds.size.height+20; self.webView.frame=viewBounds; } [super viewWillDisappear:animated]; }
五:不错的使用总结:
六:JS跟OC交互实例
1:由于Cordoval要跟JS交互都是要利用CDVPlugin进行
#import <Foundation/Foundation.h> #import <Cordova/CDVPlugin.h> @interface CDVHelloWorld : CDVPlugin -(void)sayHello:(CDVInvokedUrlCommand *)command; @end
因此咱们建立一个插件类,继承于CDVPlugin类,其中CDVInvokedUrlCommand就是用于交互的类;
#import "CDVHelloWorld.h" @implementation CDVHelloWorld -(void)sayHello:(CDVInvokedUrlCommand *)command { //接收JS传过来的值 NSDictionary *options=[command argumentAtIndex:0 withDefault:nil]; //对应键名 NSString *curValue=options[@"quality"]; UIAlertView *myAlertView=[[UIAlertView alloc]initWithTitle:@"我是小实例" message:[NSString stringWithFormat:@"当前的内容从JS传过来的值为:%@",curValue] delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"肯定", nil]; [myAlertView show]; //数据回调 if ([curValue isEqualToString:@"200"]) { curValue=@"201"; } CDVPluginResult *pluginResult=[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"OC回调过来的值"]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @end
上面的实例有接收JS传过来的值,也有再回调给JS的值,回调时要利用self.commandDelegate;其中CDVPluginResult里面包括不少状态,上面只是把正确的状态赋值传回去,而messageAsString只是会字符串,还有其它类型的,比较字典、数组等;
2:config.xml修改配置,注册刚才咱们注册的这个插件,给它定义一个HelloWorld的名字,value则是咱们刚才建立的类名
<feature name="HelloWorld"> <param name="ios-package" value="CDVHelloWorld" /> </feature>
3:Html跟JS的代码,sayHello则是咱们类中的一个方法名,HelloWorld则是咱们在配置中的那个名字,能够对它进行传参;
<!DOCTYPE html> <html> <head> <title>Capture Photo</title> <script type="text/javascript" charset="utf-8" src="cordova.js"></script> <script type="text/javascript" charset="utf-8"> //简单跟OC交互,没有回调 //function test() //{ // options={quality:"200"}; // cordova.exec(null,null,'HelloWorld','sayHello',[options]); //} function test() { options={quality:"200"}; cordova.exec( function(result){ var s=result; alert(s); }, function(error) { alert("error",error); } ,'HelloWorld','sayHello',[options]); } </script> </head> <body> <button onclick="test();">交互OC</button> <br> </body> </html>
能够查看文章对于插件的编写有进一步的说明,http://www.jianshu.com/p/e982b9a85ae8
七:分享Cordova不错的文章:
使用Cordova进行iOS开发 (环境配置及基本用法) :http://www.jianshu.com/p/d24219c008b6
使用Cordova进行iOS开发 (第三方插件的使用:Camera插件):http://www.jianshu.com/p/1e3d0c915dbc
使用Cordova进行iOS开发 (已存的项目中添加Cordova及自定义插件):http://www.jianshu.com/p/e982b9a85ae8
Cordova插件开发入门(IOS版OC跟JS交互):http://my.oschina.net/crazymus/blog/516388
浅析 Cordova for iOS(OC跟JS交互的说明):http://www.cocoachina.com/industry/20130520/6238.html
cordova CDVViewController解析 :http://blog.csdn.net/u011417590/article/details/50895734
附整理的Cordova小实例:https://github.com/wujunyang/jiaCordovaDemo
最近有个妹子弄的一个关于扩大眼界跟内含的订阅号,天天都会更新一些深度内容,在这里若是你感兴趣也能够关注一下(嘿对美女跟知识感兴趣),固然能够关注后输入:github 会有个人微信号,若是有问题你也能够在那找到我;固然不感兴趣无视此信息;