準(zhǔn)備工作:
1.在創(chuàng)建UIWebView的類中,導(dǎo)入頭文件:
#import <JavaScriptCore/JavaScriptCore.h>
2.在webView的代理方法中的任意一個(gè)方法中創(chuàng)建JSContext對(duì)象,我一般是在finisLoad里面創(chuàng)建
代理方法
-(void)webViewDidStartLoad:(UIWebView *)webView;
-(void)webViewDidFinishLoad:(UIWebView *)webView;
創(chuàng)建JSContext對(duì)象:
-(void)webViewDidFinishLoad:(UIWebView *)webView{
__weak typeof(self) weakSelf = self;
//創(chuàng)建JSContext上下文對(duì)象
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//監(jiān)聽地理位置 @“getPaymetCertAuthMsg” 這個(gè)就是JS提供的方法,供OC調(diào)用
_context[@"getPaymetCertAuthMsg"] = ^() {
NSLog(@"當(dāng)前線程:%@",[NSThread currentThread]);
};
}
//監(jiān)聽返回按鈕
Phone *phone = [Phone new];
phone.block = ^{
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController popViewControllerAnimated:YES];
});
};
_context[@"Phone"] = phone;
一. OC調(diào)用JS方法:JS提供一個(gè)方法供OC調(diào)用
在OC調(diào)用JS的方法中,如果我們需要傳遞多個(gè)參數(shù),第一種就是我下面寫的這樣的,多個(gè)參數(shù)分開寫,還有一個(gè)就是封裝成json,然后傳過去
例如:
假數(shù)據(jù): NSSting *strData = @" {
"name" : "lxy"
"age" : 17
}"
NSString *jsStr1 = [NSString stringWithFormat:@"recPaymetCertAuthMsg('%@')",strData];
[weakSelf.webView stringByEvaluatingJavaScriptFromString:jsStr1];
JS的方法名是: recPaymetCertAuthMsg
方式1:不依賴JavaScriptCore。主要調(diào)用:stringByEvaluatingJavaScriptFromString 這個(gè)方法。
如下
NSString *jsStr1 = [NSString stringWithFormat:@"recPaymetCertAuthMsg('%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@')",isloca,@"2",latitude,longitude,ipStr,@"",iMei,@"",ipType,@"",phoneType,phoneStr ];
[weakSelf.webView stringByEvaluatingJavaScriptFromString:jsStr1];
方式2:依賴JavaScriptCore。主要調(diào)用:evaluateScript 這個(gè)方法。
如下
NSString *jsStr1 = [NSString stringWithFormat:@"recPaymetCertAuthMsg('%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@','%@')",isloca,@"2",latitude,longitude,ipStr,@"",iMei,@"",ipType,@"",phoneType,phoneStr ];
[weakSelf.context evaluateScript:jsStr1];
二.JS調(diào)用OC方法
方式1:利用:JSContext 如下
在創(chuàng)建完JSContext對(duì)象之后,當(dāng)JS方法調(diào)用window.getPaymetCertAuthMsg()時(shí), OC中就會(huì)走到下面方法中的For循環(huán)那里
所以JS調(diào)用OC的核心代碼就是:
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//監(jiān)聽地理位置 @“getPaymetCertAuthMsg” 這個(gè)就是JS提供的方法,供OC調(diào)用
_context[@"getPaymetCertAuthMsg"] = ^() {
//如果JS方法還有返回值,則會(huì)在下面的打印中打印出來。
NSArray *array = [JSContext currentArguments];
for(JSValue * str in array){
NSLog(@"從js代碼傳入的值:%@",str.toString);
};
方式二:利用JavaScriptcore的協(xié)議<JSExport>:
在進(jìn)行這種交互方式之前,我們先要和JS開發(fā)者確認(rèn)一件事情,那就是調(diào)用JS方法時(shí)候的類是哪個(gè)類,需要一個(gè)類名字符串
我舉個(gè)栗子:
假如JS定義為: Phone.gotoBack() 這樣一個(gè)方法。
那么我們首先就要在OC代碼里面先創(chuàng)建一個(gè)命名為Phone的類
如下截圖:

再接著需要在這個(gè)類里面創(chuàng)建一個(gè)繼承<JSExport>的協(xié)議,并實(shí)現(xiàn)協(xié)議中的方法
在 #import"Phone.h" 中寫入下面的協(xié)議
@protocol PhoneDelegate <JSExport>
-(void)gotoBack:(NSString *)url;
@end
在 #import"Phone.m" 中實(shí)現(xiàn)和JS定義好的方法:gotoBack
-(void)gotoBack:(NSString *)url{
NSLog(@"Phone:%@",url);
//URL為JS傳過來的參數(shù),類型為字符串,如果有多個(gè)參數(shù),則封裝為JSON字符串過來,然后再解析取出對(duì)應(yīng)數(shù)據(jù)
if ([url isEqualToString:@"backZJBank"]) {
//do some thing
}
}
使用Phone的方式:
-(void)webViewDidFinishLoad:(UIWebView *)webView{
__weak typeof(self) weakSelf = self;
//創(chuàng)建JSContext上下文對(duì)象
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//監(jiān)聽返回按鈕
Phone *phone = [Phone new];
phone.block = ^{
dispatch_async(dispatch_get_main_queue(), ^{
//返回上一層控制器
[self.navigationController popViewControllerAnimated:YES];
});
};
_context[@"Phone"] = phone;
}
注:當(dāng)JS調(diào)用gotoBack方法時(shí),Phone類中的-(void)gotiBack:(NSSting *)url;方法就會(huì)被調(diào)用
3.攔截URL的方式進(jìn)行交互
在webView的代理方法中,攔截URL進(jìn)行交互
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSString *ab = request.URL.absoluteString;
NSLog(@"攔截到的連接URL:%@",[request.URL scheme]);
[self hoadUpUrlInWebView:ab];
return YES;
}
//攔截特定的URL,然后做相應(yīng)的處理
-(void)hoadUpUrlInWebView:(NSString *)urlStr{
//自定義的協(xié)議頭,然后進(jìn)入相應(yīng)的判斷邏輯里
NSString *scheme = @"zxbank://direct.grcbank.com";
//如果包含這個(gè)字符串,則進(jìn)入判斷邏輯處理
if ([urlStr hasPrefix:scheme]) {
//自定義的相應(yīng)功能的字符串@“takePhoto”
if([urlStr containsString:@"takePhoto"]){
//進(jìn)入到相應(yīng)功能,比如拍照
}
}