前言
在iOS開發(fā)中,我們經(jīng)常需要加載網(wǎng)頁演侯,在很多時候難免需要和網(wǎng)頁進(jìn)行交互,而這種交互實(shí)質(zhì)上就是UIWebView與JavaScript之間的交互,在iOS7蘋果增加了JavaScriptCore來實(shí)現(xiàn)這種交互眯漩,那么在iOS之前是怎樣來的呢?在這篇文章中就圍繞這些問題來講述麻顶。
iOS執(zhí)行JavaScript代碼
客戶端向JS傳遞數(shù)據(jù)赦抖,通過插入JS方法來實(shí)現(xiàn),通過UIWebView的這個方法- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script可以執(zhí)行JavaScript代碼:
//定義一個js函數(shù)辅肾,函數(shù)的功能是彈出一個內(nèi)容為“哈哈”的警告框队萤。
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"function showMessageAction(){alert('哈哈');}"]];
那么JavaScript就直接調(diào)用window.showMessageAction()就可以調(diào)用這個方法啦。通過這樣的方式矫钓,我們不但可以定義JavaScritp函數(shù)要尔、執(zhí)行JavaScritp函數(shù)舍杜,也可以傳遞數(shù)據(jù)(直接返回就行啦)。由于android的addJavascriptInterface()方法中有兩個參數(shù)赵辕,若第二個參數(shù)傳入字符串既绩,比如test,則JS的調(diào)用需要更改為 window.test.showMessageAction()。為了使IOS與android的調(diào)用保持一致还惠,則需要對js進(jìn)行修改饲握,具體修改形式:
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"var test = {}; (function initialize() { test.showMessageAction = function showMessageAction(){ alert('哈哈'); }; })()"]];
這樣在IOS環(huán)境下JS也可以通過調(diào)用 window.test.showMessageAction()來獲取用戶名了。
JavaScript調(diào)用oc代碼
在JavaScriptCore出現(xiàn)之前蚕键,似乎沒有專門的API來做這件事救欧,但是還是可以通過一些辦法來達(dá)到此目的。這里討論的實(shí)現(xiàn)思想是通過對UIWebView的delegate方法
-(BOOL)webView: shouldStartLoadWithRequest: navigationType:
進(jìn)行處理來實(shí)現(xiàn)的锣光。劫持UIWebview所加載的url來判斷是否是需要處理的條件即可笆怠。
- 首先我們定義一種URL格式:
協(xié)議名:函數(shù)名?參數(shù)1&參數(shù)2&…… - 接著在JavaScript中調(diào)用一個如下方法:
document.location = "協(xié)議名:函數(shù)名?參數(shù)1&參數(shù)2&……";
- 最后在UIWebView監(jiān)聽加載的URL,并就此作出相應(yīng)的操作誊爹。
例如:
- 先在html中寫一個如下的按鈕:
<button type="button" name="btn2" id="btn2" value="提示" onclick="javaScript:button2Action();">js調(diào)用OC彈出框</button>
- 接著寫一個如下JavaScript函數(shù):
function button2Action()
{
document.location = "test:showAlertView?提示&OC彈出框&確定";
}
- 最后對UIWebView的delegate方法
-(BOOL)webView: shouldStartLoadWithRequest: navigationType:
進(jìn)行處理:
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
// 處理事件
NSString *requestString = [[[request URL] absoluteString] stringByRemovingPercentEncoding];
NSLog(@"%@", requestString);
NSArray *requestsArr = [requestString componentsSeparatedByString:@":"];
if (requestsArr != nil && [requestsArr count] > 0) {
NSString *pocotol = [requestsArr objectAtIndex:0];
if ([pocotol isEqualToString:@"test"]) {
NSString *commandStr = [requestsArr objectAtIndex:1];
NSArray *commandArr = [commandStr componentsSeparatedByString:@"?"];
if (commandArr != nil && [commandArr count] > 0) {
NSString *command = [commandArr objectAtIndex:0];
NSString *parameterStr = [commandArr objectAtIndex:1];
NSArray *parameterArray = [parameterStr componentsSeparatedByString:@"&"];
if ([command isEqualToString:@"showAlertView"]) {
NSString *title;
NSString *message;
NSArray *otherButtonTitles;
if (parameterArray && parameterArray.count > 0) {
title = parameterArray[0];
}
if (parameterArray && parameterArray.count > 1) {
message = parameterArray[1];
}
if (parameterArray && parameterArray.count > 2) {
otherButtonTitles = [parameterArray subarrayWithRange:NSMakeRange(2, parameterArray.count - 2)];
}
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *alertAction;
for (NSString *buttonTitle in otherButtonTitles) {
alertAction = [UIAlertAction actionWithTitle:buttonTitle style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:alertAction];
}
[self presentViewController:alertController animated:YES completion:nil];
}
}
return NO;
}
}
return YES;
}
通過這樣的方式來做交互骑疆,需要iOS程序員和前端程序員協(xié)商好它們之間的關(guān)系,總體說來還是比較麻煩的替废。