iOS开发之笔记摘录

iOS与Html交互 跨平台开发

2017-11-28  本文已影响9673人  平安喜乐698
1. iOS与HTML交互(开发速度快)
5种方式:
        1. WKWebView
        2. UIWebView
        3. 原生javascriptcore.framework框架
        4. 第三方WebViewJavascriptBridge框架

方式一:WKWebView(iOS8后)

#import <WebKit/WebKit.h>    

    // 1 创建WebView
    WKWebView *webView=[[WKWebView alloc]initWithFrame:CGRectMake(0, 0, 0, 0) configuration:({
        
        // 1.创建配置类
        WKWebViewConfiguration *config=[WKWebViewConfiguration new];
        // 1.1设置偏好设置
        config.preferences=({
            WKPreferences *pre=[WKPreferences new];
            pre.minimumFontSize=10;                             // 最小字体(默认:0)
            pre.javaScriptEnabled=true;                         // js是否可用(默认:true)
            pre.javaScriptCanOpenWindowsAutomatically=false;    // js是否能通过窗口打开(默认:false)
            
            pre;
        });
        // 1.2设置内容处理池
        config.processPool=[WKProcessPool new];
        // 1.3设置交互(通过js)
        [config setUserContentController:({
            
            WKUserContentController *userC=[WKUserContentController new];
            [userC addScriptMessageHandler:self name:@"ssbb"];              // 添加交互,当收到js调用ssbb后 回调didReceiveScriptMessage <WKScriptMessageHandler>
            
            userC;
        })];
        
        config;
    })];
    // 1.1 dele <WKUIDelegate,WKNavigationDelegate>
    [webView setUIDelegate:self];
    [webView setNavigationDelegate:self];
    // 1.2 loadRequest
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"url"]]];
    [self.view addSubview:webView];
    // 其他

    // onlyRead
    // 标题:webView.title  url地址:webView.URL  是否正在加载:webView.loading  加载进度:webView.estimatedProgress  是否加密:webView.hasOnlySecureContent  是否支持手势前进后退:webView.allowsBackForwardNavigationGestures  是否允许预览链接:webView.allowsLinkPreview


    // 是否允许向后,是否允许向前向后,向前,重新加载,重新加载初始网址,停止加载
    [webView canGoBack];
    [webView canGoForward];
    [webView goBack];
    [webView goForward];
    [webView reload];
    [webView reloadFromOrigin];
    [webView stopLoading];
    // 加载fileURL,data
    [webView loadFileURL:[NSURL URLWithString:@""] allowingReadAccessToURL:[NSURL URLWithString:@""]];
    [webView loadData:[NSData data] MIMEType:@"" characterEncodingName:@"" baseURL:[NSURL URLWithString:@""]];
    // 加载html
    NSString *urlStr=[[NSBundle mainBundle]pathForResource:@"index.html" ofType:nil];
    [webView loadHTMLString:[NSString stringWithContentsOfFile:urlStr encoding:NSUTF8StringEncoding error:nil] baseURL:[NSURL URLWithString:urlStr]];

    // 调用js中的方法
    [webView evaluateJavaScript:@"" completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
    }];
    // 获取页面前进后退列表
    WKBackForwardList *list=webView.backForwardList;
    // 当前
    WKBackForwardListItem *item=list.currentItem;
    // only
    // item.URL(url) item.title(title) item.initialURL(原始URL)
    // 后一个
    WKBackForwardListItem *itemBack=list.backItem;
    // 前一个
    WKBackForwardListItem *itemForward=list.forwardItem;
    // 后列表
    NSArray *backList=list.backList;
    // 前列表
    NSArray *forwardList=list.forwardList;
    // 前进或后退到指定页
    [webView goToBackForwardListItem:[list itemAtIndex:0]];
#pragma mark dele <WKScriptMessageHandler>
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    // message.name
    // message.body    
}



#pragma mark dele<WKUIDelegate>
// 创webView时回调
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
}
// webView关闭时调用
-(void)webViewDidClose:(WKWebView *)webView{
}
// js中调用alert时调用
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
}
// js中调用confirm时调用
-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
}
// js中调用prompt时调用
-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
}



#pragma mark dele<WKNavigationDelegate>
// 是否允许跳转
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    
    // navigationAction.targetFrame navigationAction.sourceFrame
    
    NSString *hostStr=navigationAction.request.URL.host.lowercaseString;
    if(navigationAction.navigationType==WKNavigationTypeLinkActivated && ![hostStr containsString:@".com"]){
        // 不允许
        decisionHandler(WKNavigationActionPolicyCancel);
    }else{
        // 允许
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}
// 响应是否跳转 完成后回调
-(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    
    // onlyRead:
    // navigationResponse.forMainFrame(是否是main frame) navigationResponse.response(获取响应response) navigationResponse.canShowMIMEType
}
// 开始跳转后调用
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{}
// 重定向后调用
-(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{}
// 向前跳转失败后调用
-(void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{}
// 跳转失败后调用
-(void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error{}
// 收到内容后调用
-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{}
// 内容加载完成后调用
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{}
// https则调用
-(void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{}
// 内容处理中断时调用
-(void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{}

方式二/三:UIWebView+javascriptcore.framework

原生方式:
    #import <JavaScriptCore/JavaScriptCore.h>
    <UIWebViewDelegate>
    OC中可以直接调用JS方法,JS可通过拦截url间接调用OC
UIWebView
        // 创建UIWebView
        UIWebView *webV=[UIWebView new];
        [self.view addSubview:webV];
        // 位置布局。。。
        // loadRequest(加载网页)
        [webV loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"url"]]];
        

其他属性
        // 
        [webV setScalesPageToFit:true];
        // 滚动速度:正常速,默认慢速
        [webV.scrollView setDecelerationRate:UIScrollViewDecelerationRateNormal];
dele

        // dele
        [webV setDelegate:self];

// 加载完成后调用
-(void)webViewDidFinishLoad:(UIWebView *)webView{

》》》》》OC调js

    // 初始化一些操作  (如:提交表单,插入内容,删除内容,修改内容,查询内容)
    [webView stringByEvaluatingJavaScriptFromString:@"js代码"];
    
举例:
    // 提交表单
    [webView stringByEvaluatingJavaScriptFromString:@"document.froms[0].submit();"];
    
    // 插入内容
    [webView stringByEvaluatingJavaScriptFromString:@" js 代码"];
    // 例:
    @"var script=document.createElement('script');"   // 可以是普通控件如img(.src .width .height)
    @"script.type='text/javascript';"
    @"script.text=\"function myFun(){"
    @"var f=document.getElementsByName(‘q’)[0];"
    @"f.value='11';"
    @"document.forms[0].submit();"
    @"}\";"
    @"document.getElementsByTagName('head')[0].appendChild(script);"
    
    // 删除内容
    [webView stringByEvaluatingJavaScriptFromString:@"document.getElementById('a').remove()"];
    
    // 修改内容值、显示值
    [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByName('a')[0].value='123'"];
    [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByName('a')[0].innerHTML='h123'"];
    
    // 查询内容
    // url
    NSString *urlStr=[webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
    // title : document.title


    // 禁用 页面元素选择
    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];    
    // 禁用 长按弹出ActionSheet
    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];


方式三:原生JavaScriptCore.framework框架(iOS7),实现-----JS直接调用OC
    #import<JavaScriptCore/JavaScriptCore.h>


》》》》》 js调用OC
    /* 2种方式:
        1、Block:暴露单个方法(不能直接使用JSValue、JSContext,造成循环引用)
        2、JSExport协议:暴露单个对象
     */

方式一(Block):
OC代码
     #import <JavaScriptCore/JavaScriptCore.h>
    // 获取 js代码的执行环境
    JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    // Block (注册)
    context[@"js中的函数名"] = ^{
        NSArray *arg = [JSContext currentArguments];
    };
    context[@"js中的函数名"] = ^(NSDictionary *dic){
        NSLog(@"函数的实参值:%@", dic[@"color"]);
    };
js代码
    function testClick(){
        var str1=document.getElementById("text1").value;
        var str2=document.getElementById("text2").value;
        函数名(str1,str2);
    }
      
方式二(<JSExport>):
    实现协议遵守<JSExport>,JS中调用时(会将方法转为驼峰式,也可以使用宏JSExportAs(sbAdd,+(void)method:(int)a with:(int)b))此宏只对带参有效
    JS中调用:对象.属性 , 对象.方法   (不能在这增加成员变量)
}



// 是否允许加载网络请求
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{

》》》》》 js调用OC    
    //
    NSString *urlStr=request.URL.absoluteString;
    //
    NSRange range=[urlStr rangeOfString:@"ssbb://"];
    if(range.location!=NSNotFound){
    
        NSString *method=[urlStr substringFromIndex:range.location+range.length];
        [self performSelector:NSSelectorFromString(method)];
        return false;
    }
    
    return true;
}
// 开始加载后调用
-(void)webViewDidStartLoad:(UIWebView *)webView{}
// 加载失败后调用
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{}

注意事项

1.JS值的包装
        JS中的值拿到OC中是不能直接用的
        不能作为OC对象的属性

    JSValue *value=[context evalutateScript:@"2+2"];     [value toInt32];
    /*
     OC type            JS type
     
     nil                undefined
     NSNull             null
     NSString           string
     NSNumber           number,boolean
     NSDictionary       Object object
     NSArray            Array object
     NSDate             Date Object
     NSBlock            Function Object
     id                 Wrapper object
     Class              Constructor object
     */

方式四: WebViewJavascriptBridge框架(第三方框架)

    原理:拦截URL

         pod 'WebViewJavascriptBridge'
         #import "WebViewJavascriptBridge.h"
        // 基于WKWebView,不用再设置WKWebView 的navigationDelegate(navDele为bridge)
        // 基于UIWebView,不用再设置dele(dele为bridge)
        
        // 0.开启日志调试
        [WebViewJavascriptBridge enableLogging];
        // 1.创建WKWebView或UIWebView
        // 2.创建JavascriptBridge
        WebViewJavascriptBridge *_webViewBridge=[WebViewJavascriptBridge bridgeForWebView:webView];
        [_webViewBridge setWebViewDelegate:self];
        // 2.1配置
        // js调OC(注册多个handleName,用于js中调用)
        [_webViewBridge registerHandler:@"getUserIdFromOC" handler:^(id data, WVJBResponseCallback responseCallback) {
            // data
            // callBack
            if(responseCallback){
                responseCallback(@{@"userId":@"ssbb"});
            }
        }];
        // OC调js
        [_webViewBridge callHandler:@"getUserName" data:@{@"name":@"ssbb"} responseCallback:^(id responseData) {
            // responseData
        }];
~~~~~~~~JS

<script>    
      /*这段代码固定,必须要放到js中(第一次加载HTML时起作用,目的是加载一次wvjbscheme://__BRIDGE_LOADED__,注册JS方法)*/
      function setupWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
        if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
        window.WVJBCallbacks = [callback];
        var WVJBIframe = document.createElement('iframe');
        WVJBIframe.style.display = 'none';
        WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
        document.documentElement.appendChild(WVJBIframe);
        setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
      }
    
      /*与OC交互的所有JS方法都要放在此处注册,才能调用通过JS调用OC或者让OC调用这里的JS*/
      setupWebViewJavascriptBridge(function(bridge) {
       
       /*注册OC调JS*/
      bridge.registerHandler('openWebviewBridgeArticle', function() {
         log("openWebviewBridgeArticle was called with by ObjC")
      })
      /*注册OC调JS*/
      bridge.registerHandler('token', function(data, responseCallback) {
         log("G星爷: ", data)
         responseCallback({这里给我返回拼接后的地址})
      })

       /* 注册js调OC */
       document.getElementById('register').onclick = function () {
          bridge.callHandler('ww', {'blogdURL': 'weidsfdl'}, function(response) {
                          log('JS got response', response)
                          })
       }
     })
</script>
2.流行的跨平台开发框架
    1. Ionic Cordova
    2. React Native    (http://reactnative.cn)
    3. 5+Runtime
    4. AppCan          (http://www.appcan.cn)
    5. Framework7
    6. Jquery Mobile
2.1 Cordova
  1. 简介
支持平台
    iOS 
    Android 
    bada (Samsung) 
    Firefox OS 
    Windows Phone 7 and Windows Phone 8 (Microsoft) 
    Windows 8 (Microsoft) 
    Tizen (originally Samsung, now the Linux Foundation) 
    BlackBerry 10 (BlackBerry) 


Ionic 和cordova 的区别
    Ionic负责页面实现,cordova负责包装页面成原生App(负责页面和手机核心功能的交互)。

Ionic(IonicFramework)
    是一款开源的Html5 App开发框架(封装Angular使适用于移动端)基于跨平台移动app开发框架PhoneGap。
PhoneGap(负责网页与硬件进行交互)
    是一个基于HTML,CSS和JavaScript开发跨平台应用的平台,允许js与手机核心功能及硬件(如:摄像头,相册)进行交互。
Angular(负责网页实现)
    是单独的js库,和jQuery一样能独立开发应用
优点:
    短时间内开发出跨平台应用。
缺点:
    速度:混合应用程序相比本地应用程序反应慢,因此对于需要大量数据和功能的大型应用程序不适合使用Cordova。
    测试:跨浏览器兼容性可能会导致很多问题,需要测试不同平台。
    兼容:一些插件和不同的设备或平台存在兼容性问题。
框架架构:
Cordova架构

1.2 环境搭建与创建项目

环境搭建

安装

1.安装node
    https://nodejs.org/en/
2.安装cordova 与 ionic
    sudo npm install -g cordova (提示:added 611 packages in 22.41s则成功)
    或 sudo npm install -g cordova ionic


3.1 更新
    sudo npm update -g cordova ionic
3.2 卸载
    sudo npm uninstall cordova -g

4.安装plugman(用于安装和管理插件)
    sudo npm  install  -g   plugman
    plugman -v              查看版本(是否安装成功)
    plugman install         安装
    plugman uninstall       卸载
    plugman fetch           复制
    plugman prepare         更新配置文件
    plugman adduser         添加账户到注册表
    plugman publish         发布插件到注册表
    plugman unpublish       取消发布插件到注册表
    plugman search          搜索插件在注册表
    plugman config          配置注册表
    plugman create          创建自定义插件
    plugman platform        给自定义的插件添加或删除平台

    // 例:安装卸载camera插件
    plugman install --platform android --project platforms\android --plugin cordova-plugin-camera
    plugman uninstall --platform android --project platforms\android --plugin cordova-plugin-camera

cordova项目

使用
1.新建项目
    sudo cordova create HelloWorld
或
    sudo cordova create HelloWorld com.example.hello HelloW [--template templatePath]
        HelloWorld:文件夹名
        com.example.hello:AppID
        HelloW:程序名
        --template:项目模版
2.添加ios开发(后 可以直接在文件夹中运行项目)
    cd HelloWorld
    sudo cordova platform add ios
          其他平台android/firefoxos/blackberry10/amazon-fireos
          删除平台:sudo cordova platform rm android
3.添加插件
    sudo cordova plugin add https://github.com/petermetz/cordova-plugin-ibeacon.git
    sudo cordova plugin add cordova-plugin-console 用于打印信息
    sudo cordova plugin list  查看已安装插件
    sudo cordova plugin remove cordova-plugin-wechat  移除微信插件
    sudo cordova plugin add cordova-plugin-wechat --variable wechatappid=wx66a4c8d04580c382 安装微信插件
4.运行
    sudo cordova run ios
    或者在 HelloWorld文件夹| platforms 文件夹 | iOS 下运行


注意
    要写sudo,否则报错提示无权限

ionic项目

创建ionic账号 (终端调用ionic signup直接跳到页面)    https://dashboard.ionicjs.com/

创建ionic项目(tabs 项目style)         
    ionic start HelloWorld tabs  多次回车
添加iOS开发(出来platform文件即成功)
    sudo ionic cordova platform add ios
同步编译(有2个www文件夹,需同步,看到有3个tabbar的界面即成功)
    sudo ionic cordova build ios
如果提示无法修改文件权限,参考Mac常用终端命令篇

2 入门使用

2.0 index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Device Ready Example</title>
        <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
        <script type="text/javascript" charset="utf-8">
            
            // ---自定义方法---
            function onLoad() {
                // 添加监听
                // 设备API加载完毕后调用
                document.addEventListener("deviceready", onDeviceReady, false);
                // 应用从后台进入前台后调用
                document.addEventListener("resume", onResume, false);
            }
            function onDeviceReady() {
                // 应用进入后台调用
                document.addEventListener("pause", onPause, false);
            }
            function onPause() {
                console.log("onPause");
            }
            function onResume() {
                console.log("onResume");
其他console
    console.error("console.error");
    console.table("console.table");
    console.timeEnd("console.timeEnd");
    console.time("console.time");
    console.dirxml("console.dirxml");
    console.dir("console.dir");
    console.assert("console.assert");
    console.debug("console.debug");
    console.info("console.info");
    console.warn("console.warn");
    console.exception("console.exception");
            }
        
        </script>
    </head>
    <!--页面加载完毕后调用-->
    <body onload="onLoad()">
    </body>
</html>

2.1 插件(用于OC 与 js交互)

新建插件YTCusPlugin

#import <Cordova/CDVPlugin.h>
@interface YTCusPlugin : CDVPlugin
@end


#import "YTCusPlugin.h"
@implementation YTCusPlugin
-(void)testWithTitle:(CDVInvokedUrlCommand *)command{
    //
    if (command.arguments.count>0) {
        // arguments:js传来的参数列表
        NSString *str=command.arguments[0];
        
        [self.viewController presentViewController:[UIViewController new] animated:YES completion:^{
            // 插件结果回调类(传递数据给js)
            CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"OC回传参数"];
            // 将结果传给指定函数id
            [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
        }];
    }else{
        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"无参"];
        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
    }
}
@end

config.xml中+

    <feature name="helloPlugin">
        <param name="ios-package" value="YTCusPlugin"/>
    </feature>

html中+

    // (成功调用方法,失败调用方法,插件名(xml中对应),方法名(YTPlugin中的方法名))
    cordova.exec(testSuccess,testFailed,"helloPlugin","testWithTitle",["JS传参给VC"]);
    function testSuccess(msg) {
        alert('success: ' + msg);
    }
    function testFailed(msg) {
        alert('failed: ' + msg);
    }

2.2 自定义插件并使用

1 创建文件

package.json


test.js

var exec = require("cordova/exec");
function TestModel() {};
TestModel.prototype.testPlugin = function (success,fail,option) {
     exec(success, fail, 'testPlugin', 'testWithTitle', option);
};
var testModel = new TestModel();
module.exports = testModel;

plugin.xml

<?xml version="1.0" encoding="UTF-8" ?>
<plugin xmlns="http://phonegap.com/ns/plugins/1.0" id="com.cx.sst" version="1.0.0">
    <engines>
        <engine name="cordova" version=">=3.3.0" />
    </engines>
    
    <!--插件名-->
    <name>test</name>
    <!--插件描述-->
    <description>测试插件</description>
    
    <!--js相对位置,要调用的类-->
    <js-module src="www/test.js" name="testModel">
        <clobbers target="testModel" />
    </js-module>
    
    <!--平台-->
    <platform name="ios">
        <!--所需.m-->
        <source-file src="src/ios/YTCusPlugin.m" />
        <!--所需.h-->
        <header-file src="src/ios/YTCusPlugin.h" />
        <!--所需资源-->
        <!--<resource-file src="src/ios/1.xib" />
        <resource-file src="src/ios/2.png" />-->
        
        <config-file target="config.xml" parent="/widget">
            <!--插件名(与js对应)-->
            <feature name="test">
                <param name="ios-package" value="YTCusPlugin" />
            </feature>
        </config-file>
    </platform>
</plugin>

package.json

npm init 一直回车(注意name不能为bundle id)

YTCusPlugin

继承自CDVPlugin(同上)

2 添加插件(添加后项目的Plugins文件夹下 与 Staging/www/plugins下 会出来添加的文件)

cordova plugin add ../com.cx.sst/  可以是git地址
cordova build ios

3 测试插件

修改index.html
testModel.testPlugin(testSuccess,testFailed,["我是JS传来的参数!"]);

2.3 项目中集成Cordova

pod 'Cordova'
#import <Cordova/Cordova-umbrella.h>
    // htmlVC
    YTCustomCDViewController *htmlC=[YTCustomCDViewController new];
    // 设置初始页url
    [htmlC setStartPage:@"http://www.baidu.com"];
    [self.navigationController pushViewController:htmlC animated:true];

YTCustomCDViewController

#import <Cordova/CDVViewController.h>
@interface YTCustomCDViewController : CDVViewController
@end


#import "YTCustomCDViewController.h"
#import "CDVUserAgentUtil.h"
@interface YTCustomCDViewController ()
@end
@implementation YTCustomCDViewController
- (instancetype)init{
    if (self = [super init]){
        // 设置代理,否则无法与JavaScript方法进行交互
        self.baseUserAgent = [[CDVUserAgentUtil originalUserAgent] stringByAppendingString:@"HelloWorld"];
    }
    return self;
}
@end

YTCustomPlugin

#import <Cordova/CDVPlugin.h>
@interface YTCustomPlugin : CDVPlugin
- (void)back:(CDVInvokedUrlCommand *)command;
@end


#import "YTCustomPlugin.h"
#import <Cordova/CDVViewController.h>
#import "YTCustomCDViewController.h"
@interface YTCustomPlugin()
@property(strong, nonatomic)UIWebView *webview;
@end
@implementation YTCustomPlugin
-(UIWebView *)webview{
    if (!_webview){
        _webview = (UIWebView *)self.webView;
    }
    return _webview;
}
- (YTCustomCDViewController*)cordovaVC{
    return (YTCustomCDViewController*)self.viewController;
}
- (YTCustomCDViewController*)cordovaParentVC{
    return (YTCustomCDViewController*)self.viewController.parentViewController;
}
- (void)back:(CDVInvokedUrlCommand *)command{
    BOOL isPop = [self back];
    if (!isPop) {
        [[self cordovaVC].navigationController popViewControllerAnimated:YES];
    }
}
- (BOOL)back{
    // 当前页是否可返回
    if([self.webview canGoBack]){
        [self.webview goBack];
        return YES;
    }
    return NO;
}
@end

config.xml

<?xml version="1.0" encoding="UTF-8"?>

<!--widget:根元素  xmlns:内容固定  id:appId  version:App版本号   其他选项可选见官网-->
<widget xmlns = "http://www.w3.org/ns/widgets" id = "cx.TTTT" version = "2.0.0">
<!--App名-->
    <name>TTTT</name>
<!--App功能描述-->
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
<!--App作者-->
    <author href="http://cordova.io" email="dev@cordova.apache.org">
        Apache Cordova Team
    </author>
<!--App 可以被访问的外部域名(* 任何域名)-->
    <access origin="*"/>
<!--App开始页 位于www文件夹下-->
    <!-- <content src="http://127.0.0.1/myHome.html" /> -->
    <content src="index.html" />
<!--App 插件(用于js和OC交互)-->
    <plugin name="cordova-plugin-whitelist" version="1" />
    
<!-- Preferences for iOS  偏好设置 -->
<!--允许后台播放音乐(默认:false)-->
    <preference name="AllowInlineMediaPlayback" value="false" />
<!--Web存储方式(默认:cloud(icloud)/none/local(itunes))-->
    <preference name="BackupWebStorage" value="cloud" />
    <preference name="DisallowOverscroll" value="false" />
    <preference name="EnableViewportScale" value="false" />
    <preference name="KeyboardDisplayRequiresUserAction" value="true" />
    <preference name="MediaPlaybackRequiresUserAction" value="false" />
    <preference name="SuppressesIncrementalRendering" value="false" />
    <preference name="SuppressesLongPressGesture" value="true" />
    <preference name="Suppresses3DTouchGesture" value="false" />
    <preference name="GapBetweenPages" value="0" />
    <preference name="PageLength" value="0" />
    <preference name="PaginationBreakingMode" value="page" /> <!-- page, column -->
    <preference name="PaginationMode" value="unpaginated" /> <!-- unpaginated, leftToRight, topToBottom, bottomToTop, rightToLeft -->
    <!-- This settings is just used by the CDVViewControllerTest to assert which config file has been loaded -->
   <preference name="test_CDVConfigFile" value="config.xml" />
   
    <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>

    <allow-navigation href="https://*/*" />
    <allow-navigation href="http://*/*"  />

<!--App 可以被访问的外部域名(* 任何域名)-->
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>
    
<!--plugin:插件根元素  xmlns:命名空间(固定) id: version:插件版本号-->
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
    id="my-cordova-id" version="8.8">
<!--插件名-->
    <name>YTCustomPlugin</name>
<!--插件描述-->
    <description>Cordova YTCustomPlugin Plugin</description>
<!--插件许可证-->
    <license>Apache 2.0</license>
<!--插件关键字(英文逗号分隔)-->
    <keywords>cordova,device</keywords>
<!--每个JS-module标签对应一个JavaScript文件,src:name:-->
    <js-module src="www/device.js" name="device">
        <clobbers target="device" />
    </js-module>
<!--平台-->
    <platform name="ios">
        <config-file target="config.xml" parent="/*">
            <feature name="YTCustomPlugin">
                <param name="ios-package" value="YTCustomPlugin" />
                <param name="onload" value="true"/>
            </feature>
        </config-file>
        <header-file src="TTTT/TTTT/YTCustomPlugin.h" />
        <source-file src="TTTT/TTTT/YTCustomPlugin.m" />
    </platform>
</plugin>
</widget>

3 基础使用

3.1 存储

存储
  localStorage.setItem("key", "value");
查
  var value=localStorage.getItem("key");
  var value=localStorage.key(0); // 按字母顺序排序
  var count=localStorage.length();
删
  localStorage.removeItem("Project");
  localStorage.clear();

3.2 事件

// 添加事件监听器,而不是内联事件调用,因为Cordova 内容安全策略不允许内置Javascript
Cordova事件
  deviceReady       设备API加载完后
  pause             由前台进入后台
  resume            由后台进入前台
  backbutton        点击返回按钮(Android)
  menubutton        点击菜单按钮
  searchbutton      点击搜索按钮
  startcallbutton   点击呼叫按钮
  endcallbutton     点击结束通话按钮
  volumedownbutton  点击调低音量按钮
  volumeupbutton    点击调高音量按钮

// 
document.addEventListener("volumeupbutton", hello, false);
// 添加点击事件 
document.getElementById("helloButton").addEventListener("click", hello);

// Android点击返回按钮阻止退出程序
function onBackKeyDown(e) {
   e.preventDefault();    
}

3.3 电池状态

安装电池插件 sudo cordova plugin add cordova-plugin-battery-status
添加监听     window.addEventListener("batterystatus", onBatteryStatus, false);
            function onBatteryStatus(info) {  // 电池电量(没有%),是否插了电源
                alert("BATTERY STATUS:  Level: " + info.level + " isPlugged: " + info.isPlugged);
            }

其他事件
  batterystatus   电池状态(包括电量和是否插电源)
  batterylow      电池充电电量达到某低值(依设备不同)
  batterycritical 电池电量达到临界值

3.4 照片

安装相机插件 sudo cordova plugin add cordova-plugin-camera
添加监听     document.getElementById("button1").addEventListener
   ("click", cameraTakePicture)
            相机
            function cameraTakePicture() {
                navigator.camera.getPicture(onSuccess, onFail, {
                    quality: 50,
                    destinationType: Camera.DestinationType.DATA_URL
                    });
                    
                    function onSuccess(imageData) {
                        var image = document.getElementById('myImage');
                        image.src = "data:image/jpeg;base64," + imageData;
                    }
                    
                    function onFail(message) {
                        alert('Failed because: ' + message);
                    }
            }
            相册
            function cameraGetPicture() {
                navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
                    destinationType: Camera.DestinationType.DATA_URL,
                    sourceType: Camera.PictureSourceType.PHOTOLIBRARY
                    });
                    function onSuccess(imageURL) {
                        var image = document.getElementById('myImage');
                        image.src = imageURL;
                    }
                    function onFail(message) {
                        alert('Failed because: ' + message);
                    }
            }


其他参数
quality             图像质量(0~100,默认:50)
destinationType     返回类型
    DATA_URL或 0        返回base64编码字符串
    FILE_URI或 1        返回图片文件URI
    NATIVE_URI或 2      返回图片本机URI
sourceType          打开类型
    PHOTOLIBRARY或 0    打开照片库
    CAMERA或 1          打开本机相机
    SAVEDPHOTOALBUM或 2 打开已保存的相册
allowEdit           是否允许编辑
encodingType        编码格式
    JPEG或 0            返回JPEG编码图像
    PNG或 1             返回PNG编码图片
targetWidth         图片缩放宽度(以像素为单位)
targetHeight        图片缩放高度(以像素为单位)
mediaType           允许选择的类型
    PICTURE或 0         仅允许选择图片
    VIDEO或 1           仅允许视频选择。
    ALLMEDIA或 2        允许选择所有媒体类型
correctOrientation  校正图像的方向
saveToPhotoAlbum    将图像保存到相
popoverOptions      在IOS上设置popover位置
cameraDirection     使用前置还是后置摄像头
    FRONT或 0           前置摄像头
    返回或 1             后置摄像头
ALLMEDIA

3.5 联系人

安装联系人插件 sudo cordova plugin add cordova-plugin-contacts
添加监听
        document.getElementById("createContact").addEventListener("click", createContact);
        document.getElementById("findContact").addEventListener("click", findContact);
        document.getElementById("deleteContact").addEventListener("click", deleteContact);
 保存
        function createContact() {
            创建
            var myContact = navigator.contacts.create({"displayName": "Test User"});
            保存
            myContact.save(contactSuccess, contactError);
            function contactSuccess() {
                alert("Contact is saved!")
            }
            function contactError(message) {
                alert('Failed because: ' + message);
            }
        }
查找
        function findContacts() {
            // 筛选option
            var options = new ContactFindOptions();
            options.filter = "";            
            options.multiple = true;
            
            fields = ["displayName"];
            查找
            navigator.contacts.find(fields, contactfindSuccess, contactfindError, options);
            function contactfindSuccess(contacts) {
                for (var i = 0; i < contacts.length; i++) {
                    alert("Display Name = " + contacts[i].displayName);
                }
            }
            function contactfindError(message) {
                alert('Failed because: ' + message);
            }
        }
删除
        function deleteContact() {
            var options = new ContactFindOptions();
            options.filter = "Test User";
            options.multiple = false;
            fields = ["displayName"];
            先查再删
            navigator.contacts.find(fields, contactfindSuccess, contactfindError, options);
            function contactfindSuccess(contacts) {
                var contact = contacts[0];
                contact.remove(contactRemoveSuccess, contactRemoveError);
                function contactRemoveSuccess(contact) {
                    alert("Contact Deleted");
                }
                function contactRemoveError(message) {
                    alert('Failed because: ' + message);
                }
            }
            function contactfindError(message) {
                alert('Failed because: ' + message);
            }
        }

3.6 用户设备信息

安装插件  sudo cordova plugin add cordova-plugin-device
添加监听
        document.getElementById("cordovaDevice").addEventListener("click", cordovaDevice);  
        function cordovaDevice() {
            alert("Cordova version: " + device.cordova + "\n" +
                  "Device model: " + device.model + "\n" +
                  "Device platform: " + device.platform + "\n" +
                  "Device UUID: " + device.uuid + "\n" +
                  "Device version: " + device.version);
        }

3.7 加速计

安装插件  sudo cordova plugin add cordova-plugin-device-motion
添加监听
        document.getElementById("getAcceleration").addEventListener("click", getAcceleration);
        document.getElementById("watchAcceleration").addEventListener("click", watchAcceleration);
获取当前加速度
        function getAcceleration(){
            获取
            navigator.accelerometer.getCurrentAcceleration(accelerometerSuccess, accelerometerError);
            function accelerometerSuccess(acceleration) {
                alert('Acceleration X: ' + acceleration.x + '\n' +
                      'Acceleration Y: ' + acceleration.y + '\n' +
                      'Acceleration Z: ' + acceleration.z + '\n' +
                      'Timestamp: '      + acceleration.timestamp + '\n');
            };
            function accelerometerError() {
                alert('onError!');
            };
        }
观察加速度        
        function watchAcceleration(){
            // 每3s查一次
            var accelerometerOptions = {
                frequency: 3000
            }
            var watchID = navigator.accelerometer.watchAcceleration(accelerometerSuccess, accelerometerError, accelerometerOptions);
            function accelerometerSuccess(acceleration) {
                alert('Acceleration X: ' + acceleration.x + '\n' +
                      'Acceleration Y: ' + acceleration.y + '\n' +
                      'Acceleration Z: ' + acceleration.z + '\n' +
                      'Timestamp: '      + acceleration.timestamp + '\n');
                      // 10s后停止调用
                      setTimeout(function() {
                                 navigator.accelerometer.clearWatch(watchID);
                                 }, 10000);
            };
            function accelerometerError() {
                alert('onError!');
            };
        }

3.8 设备方向

安装插件  sudo cordova plugin add cordova-plugin-device-orientatio
添加监听
        document.getElementById("getOrientation").addEventListener("click", getOrientation);
        document.getElementById("watchOrientation").addEventListener("click", watchOrientation);
获取设备方向
        function getOrientation(){
            navigator.compass.getCurrentHeading(compassSuccess, compassError);
            function compassSuccess(heading) {
                alert('Heading: ' + heading.magneticHeading);
            };
            function compassError(error) {
                alert('CompassError: ' + error.code);
            };
        }
观察设备方向
        function watchOrientation(){   
            var compassOptions = {
                frequency: 3000
            }
            var watchID = navigator.compass.watchHeading(compassSuccess, compassError, compassOptions);
            function compassSuccess(heading) {
                alert('Heading: ' + heading.magneticHeading);
                setTimeout(function() {
                           navigator.compass.clearWatch(watchID);
                           }, 10000);
            };
            function compassError(error) {
                alert('CompassError: ' + error.code);
            };
        }

3.9 对话框

安装插件  sudo cordova plugin add cordova-plugin-dialogs
添加监听
        document.getElementById("dialogAlert").addEventListener("click", dialogAlert);
        document.getElementById("dialogConfirm").addEventListener("click", dialogConfirm);
        document.getElementById("dialogPrompt").addEventListener("click", dialogPrompt);
        document.getElementById("dialogBeep").addEventListener("click", dialogBeep);
Alert
        function dialogAlert() {
            内容
            var message = "I am Alert Dialog!";
            标题
            var title = "ALERT";
            button名
            var buttonName = "Alert Button";
            navigator.notification.alert(message, alertCallback, title, buttonName);
            function alertCallback() {
                console.log("Alert is Dismissed!");
            }            
        }
Confirm
        function dialogConfirm() {
            var message = "Am I Confirm Dialog?";
            var title = "CONFIRM";
            var buttonLabels = "YES,NO";
            navigator.notification.confirm(message, confirmCallback, title, buttonLabels);
            function confirmCallback(buttonIndex) {
                console.log("You clicked " + buttonIndex + " button!");
            }   
        }
输入框
        function dialogPrompt() {
            var message = "Am I Prompt Dialog?";
            var title = "PROMPT";
            var buttonLabels = ["YES","NO"];
            var defaultText = "Default"
            
            navigator.notification.prompt(message, promptCallback, title, buttonLabels, defaultText);
            function promptCallback(result) {
                console.log("You clicked " + result.buttonIndex + " button! \n" +
                            "You entered " +  result.input1);
            }
        }
通知音
        function dialogBeep() {
            var times = 2;
            navigator.notification.beep(times);
        }

3.10 文件系统

安装插件  sudo cordova plugin add cordova-plugin-file
添加监听
        document.getElementById("createFile").addEventListener("click", createFile);
        document.getElementById("writeFile").addEventListener("click", writeFile);
        document.getElementById("readFile").addEventListener("click", readFile);
        document.getElementById("removeFile").addEventListener("click", removeFile);
创建文件
        function createFile() {
            // 或WINDOW.PERSISTENT
            var type = window.TEMPORARY;
            // 大小5M
            var size = 5*1024*1024;    
            // 是否拥有系统权限
            window.requestFileSystem(type, size, successCallback, errorCallback)
            function successCallback(fs) {
                // 获取文件(没有则创建)
                fs.root.getFile('log.txt', {create: true, exclusive: true}, function(fileEntry) {
                                alert('File creation successfull!')
                                }, errorCallback);
            }
            function errorCallback(error) {
                alert("ERROR: " + error.code)
            }
        }
写入文件
        function writeFile() {
            var type = window.TEMPORARY;
            var size = 5*1024*1024;
            window.requestFileSystem(type, size, successCallback, errorCallback)
            function successCallback(fs) {
                fs.root.getFile('log.txt', {create: true}, function(fileEntry) {
                                // 写入
                                fileEntry.createWriter(function(fileWriter) {
                                                       fileWriter.onwriteend = function(e) {
                                                       alert('Write completed.');
                                                       };
                                                       fileWriter.onerror = function(e) {
                                                       alert('Write failed: ' + e.toString());
                                                       };
                                                       var blob = new Blob(['hello'], {type: 'text/plain'});
                                                       fileWriter.write(blob);
                                                       }, errorCallback);
                                }, errorCallback);
                                
            }
            function errorCallback(error) {
                alert("ERROR: " + error.code)
            }
        }
读取文件
        function readFile() {
            var type = window.TEMPORARY;
            var size = 5*1024*1024;
            window.requestFileSystem(type, size, successCallback, errorCallback)
            function successCallback(fs) {
                fs.root.getFile('log.txt', {}, function(fileEntry) {
                                fileEntry.file(function(file) {
                                               var reader = new FileReader();
                                               reader.onloadend = function(e) {
                                               var txtArea = document.getElementById('textarea');
                                               txtArea.value = this.result;
                                               };
                                               reader.readAsText(file);
                                               }, errorCallback);
                                }, errorCallback);
            }
            function errorCallback(error) {
                alert("ERROR: " + error.code)
            }
        }
删除文件
        function removeFile() {
            var type = window.TEMPORARY;
            var size = 5*1024*1024;
            window.requestFileSystem(type, size, successCallback, errorCallback)
            function successCallback(fs) {
                fs.root.getFile('log.txt', {create: false}, function(fileEntry) {
                                fileEntry.remove(function() {
                                                 alert('File removed.');
                                                 }, errorCallback);
                                }, errorCallback);
            }
            function errorCallback(error) {
                alert("ERROR: " + error.code)
            }
        }

3.11 文件传输

安装插件  sudo cordova plugin add cordova-plugin-file-transfer
添加监听
        document.getElementById("uploadFile").addEventListener("click", uploadFile);
        document.getElementById("downloadFile").addEventListener("click", downloadFile);
下载文件
        function downloadFile() {
            var fileTransfer = new FileTransfer();
            var uri = encodeURI("资源服务器地址");
            var fileURL =  "设备存储地址";
            
            fileTransfer.download(
              uri, fileURL, function(entry) {
                  console.log("download complete: " + entry.toURL());
              },
              function(error) {
                  console.log("download error source " + error.source);
                  console.log("download error target " + error.target);
                  console.log("download error code" + error.code);
              },
              false, {
                  headers: {
                  "Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
                  }
              }
            );
        }
上传文件
        function uploadFile() {
            var fileURL = "设备存储地址"
            var uri = encodeURI("上传服务器地址");
            var options = new FileUploadOptions();
            
            options.fileKey = "file";
            options.fileName = fileURL.substr(fileURL.lastIndexOf('/')+1);
            options.mimeType = "text/plain";
            
            var headers = {'headerParam':'headerValue'};
            options.headers = headers;
            
            var ft = new FileTransfer();
            ft.upload(fileURL, uri, onSuccess, onError, options);
            function onSuccess(r) {
                console.log("Code = " + r.responseCode);
                console.log("Response = " + r.response);
                console.log("Sent = " + r.bytesSent);
            }
            function onError(error) {
                alert("An error has occurred: Code = " + error.code);
                console.log("upload error source " + error.source);
                console.log("upload error target " + error.target);
            }
        }

3.12 地理位置

安装插件  sudo cordova plugin add cordova-plugin-geolocation
添加监听        
        document.getElementById("getPosition").addEventListener("click", getPosition);
        document.getElementById("watchPosition").addEventListener("click", watchPosition);
获取位置
        function getPosition() {          
            var options = {
                enableHighAccuracy: true,
                超时时间
                maximumAge: 3600000
            }
            var watchID = navigator.geolocation.getCurrentPosition(onSuccess, onError, options);
            function onSuccess(position) {
                alert('Latitude: '          + position.coords.latitude          + '\n' +
                      'Longitude: '         + position.coords.longitude         + '\n' +
                      'Altitude: '          + position.coords.altitude          + '\n' +
                      'Accuracy: '          + position.coords.accuracy          + '\n' +
                      'Altitude Accuracy: ' + position.coords.altitudeAccuracy  + '\n' +
                      'Heading: '           + position.coords.heading           + '\n' +
                      'Speed: '             + position.coords.speed             + '\n' +
                      'Timestamp: '         + position.timestamp                + '\n');
            };
            function onError(error) {
                alert('code: '    + error.code    + '\n' + 'message: ' + error.message + '\n');
            }
        }
观察位置       
        function watchPosition() {
            // 
            var options = {
                maximumAge: 3600000,
                // 3s查一次
                timeout: 3000,
                enableHighAccuracy: true,
            }
            var watchID = navigator.geolocation.watchPosition(onSuccess, onError, options);
            function onSuccess(position) {
                alert('Latitude: '          + position.coords.latitude          + '\n' +
                      'Longitude: '         + position.coords.longitude         + '\n' +
                      'Altitude: '          + position.coords.altitude          + '\n' +
                      'Accuracy: '          + position.coords.accuracy          + '\n' +
                      'Altitude Accuracy: ' + position.coords.altitudeAccuracy  + '\n' +
                      'Heading: '           + position.coords.heading           + '\n' +
                      'Speed: '             + position.coords.speed             + '\n' +
                      'Timestamp: '         + position.timestamp                + '\n');
            };
            function onError(error) {
                alert('code: '    + error.code    + '\n' +'message: ' + error.message + '\n');
            }
        }

3.13 全球化

安装插件  sudo cordova plugin add cordova-plugin-globalization
添加监听  (getDeviceReady)
        document.getElementById("getLanguage").addEventListener("click", getLanguage);
        document.getElementById("getLocaleName").addEventListener("click", getLocaleName);
        document.getElementById("getDate").addEventListener("click", getDate);
        document.getElementById("getCurrency").addEventListener("click", getCurrency);
查看当前语言
        function getLanguage() {
            navigator.globalization.getPreferredLanguage(onSuccess, onError);
            function onSuccess(language) {
                alert('language: ' + language.value + '\n');
            }
            function onError(){
                alert('Error getting language');
            }   
        }
查看当前Locale
        function getLocaleName() {
            navigator.globalization.getLocaleName(onSuccess, onError);
            function onSuccess(locale) {
                alert('locale: ' + locale.value);
            }
            function onError(){
                alert('Error getting locale');
            }
        }
查看当前Date
        function getDate() {
            var date = new Date();
            var options = {
                formatLength:'short',
                日期style
                selector:'date and time'
            }
            navigator.globalization.dateToString(date, onSuccess, onError, options);
            function onSuccess(date) {
                alert('date: ' + date.value);
            }
            function onError(){
                alert('Error getting dateString');
            }
        }
查看当前货币值
        function getCurrency() {
            var currencyCode = 'EUR';
            navigator.globalization.getCurrencyPattern(currencyCode, onSuccess, onError);
            function onSuccess(pattern) {
                alert('pattern: '  + pattern.pattern  + '\n' +
                      'code: '     + pattern.code     + '\n' +
                      'fraction: ' + pattern.fraction + '\n' +
                      'rounding: ' + pattern.rounding + '\n' +
                      'decimal: '  + pattern.decimal  + '\n' +
                      'grouping: ' + pattern.grouping);
            }
            function onError(){
                alert('Error getting pattern');
            }   
        }

所有方法
  getPreferredLanguage  onSuccess,onError                 返回客户端当前的语言
  getLocaleName         onSuccess,onError                 返回客户端的当前语言环境设置。
  dateToString          日期,onSuccess,onError,选项       返回日期(根据区域设置和时区)
  stringToDate          dateString,onSuccess,onError,options    解析日期
  getCurrencyPattern    currencyCode,onSuccess,onError    返回客户端的货币模式
  getDatePattern        onSuccess,onError,options         返回客户端的日期模式
  getDateNames          onSuccess,onError,options         返回月,周或天的名称数组。
  isDayLightSavingsTime date,successCallback,errorCallback       确定夏令时是否活动(根据客户端的时区和日历)
  getFirstDayOfWeek     onSuccess,onError                  返回一周的第一天
  numberToString        number,onSuccess,onError,options  返回number
  stringToNumber        string,onSuccess,onError,options  解析一个数字
  getNumberPattern      onSuccess,onError,options          返回数字模式

3.14 打开Web浏览器

安装插件  sudo cordova plugin add cordova-plugin-inappbrowser
添加监听  
        document.getElementById("openBrowser").addEventListener("click", openBrowser);
打开Web浏览器
        function openBrowser() {
            url
            var url = 'https://cordova.apache.org';
            新窗口
            var target = '_blank';
            
            var options = "location=yes"

            var ref = cordova.InAppBrowser.open(url, target, options);
            添加监听
            开始加载
            ref.addEventListener('loadstart', loadstartCallback);
            停止加载
            ref.addEventListener('loadstop', loadstopCallback);
            加载失败
            ref.addEventListener('loadloaderror', loaderrorCallback);
            退出
            ref.addEventListener('exit', exitCallback);
            function loadstartCallback(event) {
                console.log('Loading started: '  + event.url)
            }
            function loadstopCallback(event) {
                console.log('Loading finished: ' + event.url)
            }
            function loaderrorCallback(error) {
                console.log('Loading error: ' + error.message)
            }
            function exitCallback() {
                console.log('Browser is closed...')
            }
        }

ref
  移除监听
    ref.removeEventListener(eventname, callback);
  关闭InAppBrowser
    ref.close();                            
  打开隐藏的窗口
    ref.show();
  注入JS
    var details = "javascript/file/url"
    ref.executeScript(details, callback);
  注入CSS
    var details = "css/file/url"
    ref.inserCSS(details, callback);
其他options
  location          是否显示浏览器位置栏
  hidden            是否隐藏inAppBrowser
  clearCache        是否清除浏览器缓存缓存
  clearsessioncache 是否清除会话cookie缓存
  zoom              是否显示Android浏览器的缩放控件
  hardwareback      点击硬件返回按钮后 false则退出应用,true则返回历史记录中的上一页。

3.15 媒体

安装插件  sudo cordova plugin add cordova-plugin-media
添加监听  
        document.getElementById("playAudio").addEventListener("click", playAudio);
        document.getElementById("pauseAudio").addEventListener("click", pauseAudio);
        document.getElementById("stopAudio").addEventListener("click", stopAudio);
        document.getElementById("volumeUp").addEventListener("click", volumeUp);
        document.getElementById("volumeDown").addEventListener("click", volumeDown);
播放
        var myMedia = null;
        function playAudio() {
            var src = "设备资源路径";    
            if(myMedia === null) {
                myMedia = new Media(src, onSuccess, onError);
                function onSuccess() {
                    console.log("playAudio Success");
                }
                function onError(error) {
                    console.log("playAudio Error: " + error.code);
                }
            }
            myMedia.play();
        }
暂停
        function pauseAudio() {
            if(myMedia) {
                myMedia.pause();
            }
        }
停止        
        function stopAudio() {
            if(myMedia) {
                myMedia.stop(); 
            }    
            myMedia = null;
        }
音量
        var volumeValue = 0.5;
        function volumeUp() {
            if(myMedia && volumeValue < 1) {
                myMedia.setVolume(volumeValue += 0.1);
            }
        }
        function volumeDown() {
            if(myMedia && volumeValue > 0) {
                myMedia.setVolume(volumeValue -= 0.1);
            }
        }

其他方法
  getCurrentPosition    当前播放位置
  getDuration           持续播放时间
  play                  播放
  pause                 暂停
  release               释放资源
  seekTo                更改播放位置
  setVolume             设置音量
  startRecord           开始录制
  stopRecord            停止录制
  stop                  停止播放

3.16 媒体

安装插件  sudo cordova plugin add cordova-plugin-media-capture
添加监听  
        document.getElementById("audioCapture").addEventListener("click", audioCapture);
        document.getElementById("imageCapture").addEventListener("click", imageCapture);
        document.getElementById("videoCapture").addEventListener("click", videoCapture);
启动录音机
        function audioCapture() {
            var options = {
                limit: 1,
                duration: 10
            };
            navigator.device.capture.captureAudio(onSuccess, onError, options);
            function onSuccess(mediaFiles) {
                var i, path, len;
                for (i = 0, len = mediaFiles.length; i < len; i += 1) {
                    path = mediaFiles[i].fullPath;
                    console.log(mediaFiles);
                }
            }
            function onError(error) {
                navigator.notification.alert('Error code: ' + error.code, null, 'Capture Error');
            }
        }
启动相机 拍照
        function imageCapture() {
            var options = {
                limit: 1
            };
            navigator.device.capture.captureImage(onSuccess, onError, options);
            function onSuccess(mediaFiles) {
                var i, path, len;
                for (i = 0, len = mediaFiles.length; i < len; i += 1) {
                    path = mediaFiles[i].fullPath;
                    console.log(mediaFiles);
                }
            }
            function onError(error) {
                navigator.notification.alert('Error code: ' + error.code, null, 'Capture Error');
            }
        }
启动相机 录像
        function videoCapture() {
            var options = {
                limit: 1,
                duration: 10
            };
            navigator.device.capture.captureVideo(onSuccess, onError, options);
            function onSuccess(mediaFiles) {
                var i, path, len;  
                for (i = 0, len = mediaFiles.length; i < len; i += 1) {
                    path = mediaFiles[i].fullPath;
                    console.log(mediaFiles);
                }
            }
            function onError(error) {
                navigator.notification.alert('Error code: ' + error.code, null, 'Capture Error');
            }   
        }

3.17 网络

安装插件  sudo cordova plugin add cordova-plugin-network-information
添加监听  
        document.getElementById("networkInfo").addEventListener("click", networkInfo);
        document.addEventListener("offline", onOffline, false);
        document.addEventListener("online", onOnline, false);
获取当前网络状态信息
        function networkInfo() {
            var networkState = navigator.connection.type;
            var states = {};
            states[Connection.UNKNOWN]  = 'Unknown connection';
            states[Connection.ETHERNET] = 'Ethernet connection';
            states[Connection.WIFI]     = 'WiFi connection';
            states[Connection.CELL_2G]  = 'Cell 2G connection';
            states[Connection.CELL_3G]  = 'Cell 3G connection';
            states[Connection.CELL_4G]  = 'Cell 4G connection';
            states[Connection.CELL]     = 'Cell generic connection';
            states[Connection.NONE]     = 'No network connection';   
            alert('Connection type: ' + states[networkState]);
        }
        function onOffline() {
            alert('You are now offline!');
        }
        function onOnline() {
            alert('You are now online!');
        }

3.18 启动界面

安装插件  sudo ordova plugin add cordova-plugin-splashscreen
 config.xml | widget +
<preference name = "SplashScreen" value = "screen启动图名" />
<preference name = "SplashScreenDelay" value = "3000" />                  3s后隐藏
<preference name = "SplashMaintainAspectRatio" value = "true" />          false会拉伸

3.19 震动

安装插件  sudo cordova plugin add cordova-plugin-vibration
添加监听  
        document.getElementById("vibration").addEventListener("click", vibration);
        document.getElementById("vibrationPattern").addEventListener("click", vibrationPattern);
        function vibration() {
            var time = 3000;
            navigator.vibrate(time);      震动3s
        }
        function vibrationPattern() {
            var pattern = [1000, 1000, 1000, 1000]; 
            navigator.vibrate(pattern);    隔1s震动1s
        }

3.20 白名单

config.xml+

导航白名单
  <allow-navigation href = "http://example.com/*" />
  <allow-navigation href = "*://*.example.com/*" />
意向白名单
  allow-intent 元素,用于指定允许打开系统的URL
网络请求白名单
  <access origin = "http://example.com" />
  < access origin =“*"/>
内容安全策略
  <meta http-equiv = "Content-Security-Policy" content = "default-src 
   'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 
   'self' 'unsafe-inline'; media-src *">
  <meta http-equiv = "Content-Security-Policy" content = "default-src 'self' foo.com">
  <meta http-equiv = "Content-Security-Policy" content = "default-src *; 
   style-src 'self' 'unsafe-inline'; script-src 'self' 
   'unsafe-inline' 'unsafe-eval'">

4.优化

触摸事件
  点击事件有300毫秒的延迟,使用 touchstart 和 touchend 事件而不是点击事件。
动画
  应该使用硬件加速的CSS转换而不是JavaScript动画
存储
  尽可能使用存储缓存
滚动
  应该部分加载,必要时使用装载机。
图片
  图片会减慢应用程序。应尽可能使用CSS图像精灵。图像大小要适合而不是缩放
CSS
  应该避免阴影,渐变(减慢了页面的呈现时间)
简化
  浏览器的DOM很慢,应该尽量减少DOM操作和DOM元素的数量。
测试
  在尽可能多的设备和操作系统上测试应用程序
上一篇下一篇

猜你喜欢

热点阅读