基于UIWebview的混合編程是指同時使用原生的控件和UIWebView來展現(xiàn)應用界面。合理地使用該方案可以保證應用既有原生界面的流暢交互效果,又有Web界面的良好的動態(tài)修改和多平臺復用的優(yōu)勢。
———以上摘抄自《iOS開發(fā)進階》
這一章是非常實用的一章,本文將提煉其中精華部分。
15.1 混合編程簡介
基于UIWebview的混合編程本來就是一個挺普通常見的技術(shù)框架,但是自從國外開始用Hybird來稱呼它時,這個技術(shù)突然間就變得“高大上”起來。
什么時候使用Hybird
- 排版復雜
- 界面的變化需求頻繁
- 界面對用戶的交互需求不復雜
15.2 使用模板引擎渲染HTML界面
有過網(wǎng)站開發(fā)經(jīng)驗的朋友都知道我們一般需要一個模板引擎來對界面進行渲染,如Django:
<html>
<body>
<h1>{{name}}</h1>
</body>
</html>
Django的模板引擎將替換 {{}} 中的變量為字符創(chuàng)而對界面進行顯示,在iOS中也有類似的模板引擎,我們在這里介紹一下GRMustache,GRMustache在github有很完整的使用教程,這里簡單的提一下:
安裝
- [CocoaPod]
這部分相當簡單,這部分大家可以自己去github查閱。
使用
#import “GRMustache.h"
假設我們的html文件是這樣的,template.html:
<html>
<body>
<h1>{{name}}</h1>
</body>
</html>
基本上所有的邏輯就是:
- 從html獲取到內(nèi)容
- 通過模板引擎進行字符串替換
- 講渲染后的字符串在webview上顯示
-(NSString *)getTemplateFromName:(NSString *)name data:(NSDictionary *)data{
NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:name]; //獲取到.html文件地址
NSString *template = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; //獲取.html文件內(nèi)容
NSString *content = [GRMustacheTemplate renderObject:data fromString:template error:nil]; //進行渲染
return content;
}
獲取到渲染后的模板我們需要在webview上進行顯示:
NSString *content = [self getTemplateFromName:@"template.html" data:@{@"name":@"StrongX"}];
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[self.webview loadHTMLString:content baseURL:baseURL];
OC與JS互調(diào)
OC通知JS
UIWebview有一個方法
-(nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
假設我們的JS方法是這樣的:
function funcName(userid){
…….
}
那么我們使用OC調(diào)用這個方法就是這樣的:
[_webView stringByEvaluatingJavaScriptFromString:@“funcName(123456)"];
JS通知OC
JS通知OC并沒有直接的方法,但是我們可以通過更新url的方式在UIWebview的delegate中拿到消息。
我們在js中調(diào)用方法
//js通知OC
function js_call_oc(){
var iFrame;
iFrame = document.createElement("iframe");
iFrame.setAttribute("src", "ios://StrongX");
iFrame.setAttribute("style", "display:none;");
iFrame.setAttribute("height", "0px");
iFrame.setAttribute("width", "0px");
iFrame.setAttribute("frameborder", "0");
document.body.appendChild(iFrame);
// 發(fā)起請求后這個iFrame就沒用了,所以把它從dom上移除掉
iFrame.parentNode.removeChild(iFrame);
iFrame = null;
}
我們可以看到我們設置一個“src”的屬性,而這個屬性就是我們在UIWebview的delegate中拿到字符串,如果傳遞一些簡單的參數(shù),也可以添加到這個字符串中。
我們在我們的OC代碼中:
//
_webview.delegate = self;
//
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSString *urlstr = request.URL.absoluteString;
NSRange range = [urlstr rangeOfString:@"ios://StrongX"];
if (range.length!=0) { //////////////
你要執(zhí)行的操作
////////////
}
return YES;
}
15.7 使用Safari進行調(diào)試
我們有時候可能會通過輸出的方式來進行調(diào)試,在js中會使用console.log();方法,但是你會發(fā)現(xiàn)調(diào)用這個方法并不會在xcode的控制臺輸出(廢話)。這個時候我們就可以通過safari來輔助我們進行開發(fā)。
- 我們需要打開safari的調(diào)試模式:safari->偏好設置->高級->勾選在菜單中顯示“開發(fā)”菜單

-
我們開需要在模擬器 或者真機上打開調(diào)試功能:設置->Safari->高級->Web檢查器,打開開關(guān):
打開模擬器中的檢查器
當你完成以上部分之后,當我們再運行項目,重新打開Safari(記得一定要重新啟動Safari),在開發(fā)菜單中我們可以打開web檢查器:

我們可以在web檢查器中直接對html、css、js代碼進行修改,同時在控制臺會有對js等代碼的調(diào)試、輸出。(這個類似web開發(fā)時Chrome的檢查功能)

歡迎加入iOS交流群537774852
更多文章
