Cordoval在iOS中的運用整理

 

一:關於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類則沒什麼特別的,它直接繼承自UIWebViewios

4:當CDVViewController在構建時,它有兩個很重要的屬性:NSString*wwwFolderName和NSString *startPage。這兩個屬性值使得CDVViewController在load以後直接加載wwwFolderName下的startPage做爲初始顯示的頁面。git

以上是對CDVViewController的一個簡單介紹。容易明白的是,在iOS應用中使用了CDVViewController以後,界面實際上就徹底交給了CDVCordovaView*webView,即一個UIWebViewgithub

 

 

二:使用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 會有個人微信號,若是有問題你也能夠在那找到我;固然不感興趣無視此信息;

相關文章
相關標籤/搜索