当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS开发中Cordoval运用技巧分析

iOS开发中Cordoval运用技巧分析

2018年10月09日  | 移动技术网IT编程  | 我要评论

改签被骗16万,卖之秀,凯恒大厦

ios开发中cordoval运用技巧分析。

一:关于cordoval理论知识

1:phonegap是手机平台上流行的一款中间件。它构建在各种手机平台所提供的webview(内核)的基础之上,使用javascript语言对应用开发者提供统一的接口(如调用相机、调用其他本地组件),从而屏蔽了各手机平台上os的异构。在无线小组的调研任务中,我的任务主要是负责ios平台上的调研,本文简单描述了ios平台上phonegap与平台本地的互操作性的实现。

2:phonegap因为被捐赠给了apache而改名为cordova,所以phonegap里的类名都以cdv作为前缀。在ios平台上,最重要的一个核心类是cdvviewcontroller。该类直接继承自uiviewcontroller,因而具备了所有uiviewcontroller所具备的特性。同时,该类还实现了两个protocol(即接口):uiwebviewdelegate和cdvcommanddelegate。因此它也负责uiwebview的一些callback,以及cdvinvokedurlcommand的执行。

3:cdvviewcontroller类的主要对象成员是cdvcordovaview *webview,在源代码中可以看出,这个webview对象是cdvviewcontroller的self.view上的唯一被add进来的子对象,即负责了整个cdvviewcontroller类的显示。而cdvcordovaview类则没什么特别的,它直接继承自uiwebview。

4:当cdvviewcontroller在构建时,它有两个很重要的属性:nsstring*wwwfoldername和nsstring *startpage。这两个属性值使得cdvviewcontroller在load之后直接加载wwwfoldername下的startpage作为初始显示的页面。

以上是对cdvviewcontroller的一个简单介绍。容易明白的是,在ios应用中使用了cdvviewcontroller之后,界面实际上就完全交给了cdvcordovaview*webview,即一个uiwebview。

\

 

 

二:使用cordoval常碰到的问题

config.xml 是一个用来配置应用的全局属性的文件, 在此文件中配置的属性应该是能适应所有平台的. 在编译的时候配置文件将会被编译到对应的平台中.

1:如何在cordoval加载远程的url网址

在config.xml配置文件时增加下面两个,便可以打开url的html页面

    
    

2:在cordoval中加载同一个域的url是在app打开,跳转到其它却是用safari浏览器打开

同样是在config.xml配置中把下面两个删除,这样它便会一直在app里面进行跳转

-->
-->

2.1:禁用 webviewbounce

uiwebview是ios sdk中一个最常用的控件, 在cordova中, 默认也是使用uiwebview作为默认视图显示我们的html应用的.
在使用cordova的项目中, 默认webviewbounce这个选项是打开的, 所以使用手指向下或者向上滑动屏幕时, 经常会看到页面底部和屏幕底部会出现一大片空白, 然后松开手指后, 再弹回去的特效.


2.2:config.xml access配置

只允许google.com access to google.com:


只允许google.com的https协议 access to the secure google.com (https://):


二级域名(maps) access to the subdomain maps.google.com:


所有二级域名 access to all the subdomains on google.com, for example mail.google.com and docs.google.com:


所有域名 access to all domains, for example, google.com and developer.mozilla.org:


2.3:config.xml navigation whitelist

说明:webview可以跳转至的url

















2.4:config.xml intent whitelist

说明:可以打开的链接





















2.5:config.xml network request whitelist

说明:网络请求(如xhr等)白名单















2.6: content security policy

说明:页面上的资源白名单

主要分这几类:default-src,style-src,script-src,img-src,font-src,media-src 等

参数值可以是:*,'self','unsafe-inline',data: 等

我使用的是非常宽松的策略:

允许所有域名的数据,允许不安全的内联,允许data:(主要用于base64形式的图片,字体等)

 

3:如何加载不同的启动页url地址

在配置config.xml文件中有个content的节点,里面默认是有一个打开本地的地址(比如:);这个就是跳转到本地包里面的html页面,也可以修改成(比如:);

上面这种只是修改默认的地址,可能不符合对于项目实际用法,项目中要加载cordova都会有一个viewcontroller的控制器继承于cdvviewcontroller,它时就有一个属性startpage用于设置跳到webview加载的html页面;其中使用cdvviewcontroller通常需要设置wwwfoldername的目录名称,和startpage首页的名称即可。默认wwwfoldername为www,startpage默认为;这个也是模板直接生成时文件的名称;

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=@"";

同样是在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开发初探 地址:

cordova使用pod实例 地址:【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 
#import 

@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则是我们刚才创建的类名

    
    

3:html跟js的代码,sayhello则是我们类中的一个方法名,helloworld则是我们在配置中的那个名字,可以对它进行传参;

<title></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><button onclick="test();">交互oc</button>

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网