大家知道,客户端的域名或IP地址是固定不变的,而客户端的ip地址一般是随机变换的。所以客户端可以直接通过域名向服务器发送请求消息,而服务器无法主动主动向客户端发送消息,只能通过客户端的回调来给客户端发送信息或调用客户端的函数。
那么服务器怎么随时联系客户端呢?通过客户端轮训来通过回调的方式给客户端传递消息,十分浪费流量,要不断建立http通道,既浪费时间也浪费流量以及电量,也不及时。所以最佳方式是服务器和客户端建立可信的socket连接,这样传递消息既即使,又省流量,电量。socket通信的效率是http通信效率的30倍。
而h5页面如何和客户端之间如何通信呢?它可没有能力建立socket连接啊?只能通过回调的方式通信了。
ios客户端如何调用h5页面呢?我自己写了一个通用处理类(下载地址:http://download.csdn.net/download/jia12216/10133034),很简单,几行代码就可以了。下面是调用的代码:
-(void)auctionGuide:(UIButton *)button{ AECommonJSBridgeAndProgressViewController *jsWebview = [AECommonJSBridgeAndProgressViewController new]; NSString *urlSTR= [NSString stringWithFormat:@"%@/getAuctionGuide.ns",kBaseURL]; [jsWebview setupWithUrl:urlSTR handleNameArray:[NSArray arrayWithObjects:@"callPhone", nil] handleTimes:1]; [self.navigationController pushViewController:jsWebview animated:YES]; }
简单吧?传递一个url地址就可以了。传递一个回调函数名数组就可以了。我这个h5页面最多只支持处理3个回调函数,handleTimes参数代表回调的函数个数。我的h5通用处理类会自动注册h5调用的函数。我这个类使用了ReactiveCocoa库(@weakify(self),@strongify(self);),用于处理block。在Podfile文件中增加pod ‘ReactiveCocoa’,'2.5’就可以导入ReactiveCocoa。
这个处理h5的通用类我放到资源文件里混点分。当然你也可以用其它方式调用h5,注册函数也很简单。在网上一搜一大把。
h5页面如何写回调ios客户端,我在网上查一个几十篇文章,试了很多遍,结果没有发现一个是正确的,都不能回调ios客户端。看来问题就出在细节处理上。为何没有一个详细的文章介绍呢!我毕竟不是专业 写h5页面的,把几篇文章结合一下才调用ios客户端成功。下面是h5页面回调iOS客户端注册的函数了的详细代码。
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="content-language" content="zh-CN" /> <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="format-detection" content="telephone=no" /> <meta name="keywords" content="" /> <meta name="description" content="" /> <meta name="author" content="" /> <meta name="renderer" content="webkit"> <meta name="format-detection" content="telephone=no"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1" /> <meta http-equiv="X-UA-Compatible" content="IE=9" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>竞拍指南</title> <style> *{ margin: 0; padding: 0; } .main{ width: 80%; margin: 0 auto; text-align: center; } </style> </head> <script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script> <script type="text/javascript"> var IRL =null; var userAgentStr=null; var u = navigator.userAgent, app = navigator.appVersion; function callPhone(){ var tel = document.getElementById("tel").innerText; var data = {"tel":tel}; var ua = window.navigator.userAgent.toLowerCase(); if( isbrowser().versions.ios ){ IRL.callHandler('callPhone',data, function(responseData) {alert(responseData);}); }else if(window.AndroidWebView){ RL.h5CallPhone(tel); } } function isbrowser() { // 浏览器判断 return window.browser = { versions: function () { var u = navigator.userAgent, app = navigator.appVersion; return { //移动终端浏览器版本信息 trident: u.indexOf('Trident') > -1, //IE内核 presto: u.indexOf('Presto') > -1, //opera内核 webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核 gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核 mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端 ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端 android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或uc浏览器 iPhone: u.indexOf('iPhone') > -1, //是否为iPhone或者QQHD浏览器 iPad: u.indexOf('iPad') > -1, //是否iPad webApp: u.indexOf('Safari') == -1 //是否web应该程序,没有头部与底部 }; }(), language: (navigator.browserLanguage || navigator.language).toLowerCase() }; } function InitWebViewJavascriptBridge(callback) { var ua = window.navigator.userAgent.toLowerCase(); if (window.AndroidWebView || !isbrowser().versions.ios || ua.match(/MicroMessenger/i) == 'micromessenger') { return; } function _callback(bridge) { IRL= bridge; if (callback) callback(bridge); } 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) } InitWebViewJavascriptBridge(); </script> <body> <div class="main"> 暂无 <span onclick="callPhone()" id="tel">15890341205</span> </div> </body> </html>
千万要注意要用IRL存下这个bridge,h5页面就是通过他回调的ios客户端的函数,callPhone是ios注册的函数名。我想会写h5页面都看得懂这个代码吧!我致力于让大家少走弯路,直接能使用的开发技术。我的文章都是来源于实际的app。不会有因为细节问题让大家不能使用或抄袭的别人文章。