欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS开发中Cordoval运用技巧分析

程序员文章站 2022-04-26 12:41:40
ios开发中cordoval运用技巧分析。 一:关于cordoval理论知识 1:phonegap是手机平台上流行的一款中间件。它构建在各种手机平台所提供的webview(内核)的基础之上,使用ja...

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。

iOS开发中Cordoval运用技巧分析

 

 

二:使用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:index.html 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的节点,里面默认是有一个打开本地的地址index.html(比如:);这个就是跳转到本地包里面的html页面,也可以修改成(比如:);

上面这种只是修改默认的地址,可能不符合对于项目实际用法,项目中要加载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://方式进行读取;

iOS开发中Cordoval运用技巧分析

因为可以读取沙盒里面的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];
}

五:不错的使用总结:

iOS开发中Cordoval运用技巧分析

iOS开发中Cordoval运用技巧分析

iOS开发中Cordoval运用技巧分析

iOS开发中Cordoval运用技巧分析

iOS开发中Cordoval运用技巧分析

iOS开发中Cordoval运用技巧分析

iOS开发中Cordoval运用技巧分析

六: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>