第一種:JS給OC傳值。
方法1
1. 需支持的框架:使用JavaScriptCore.framework框架
2. 使用場(chǎng)景: 網(wǎng)頁(yè)中代碼中的某個(gè)方法,比如點(diǎn)擊事件方法,將該方法的參數(shù)傳值給OC,供OC使用。
比如:在天貓App的H5界面中,點(diǎn)擊了一個(gè)商品,需要跳轉(zhuǎn)到本地的界面,那要怎么通知到控制器跳轉(zhuǎn)呢,又改怎么拿到你跳轉(zhuǎn)時(shí)所需要的參數(shù)是呢?
在UIWebView加載完畢的時(shí)候
- (void)webViewDidFinishLoad:(UIWebView*)webView{
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"funncMath"] = ^{NSArray*arg = [JSContext currentArguments];for(idobj in arg) {
NSLog(@"%@", obj);
}
};
}
其中funncMath是JS的函數(shù)名,得到的arg數(shù)組里面為JS的passValue函數(shù)的參數(shù),即JS要傳給OC的參數(shù)。
方法2
查看JS代碼
function testClick()
{
var str1=document.getElementById("text1").value;var str2=document.getElementById("text2").value;//"objc://"為自定義協(xié)議頭;//? str1&str2為要傳給OC的值,以":/"作為分隔
window.location.href="objc://"+":/"+str1+":/"+str2;
}
//遵守UIWebViewDelegate代理協(xié)議。
-(BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType{
//拿到網(wǎng)頁(yè)的實(shí)時(shí)
urlNSString*requestStr = [[request.URLabsoluteString] stringByRemovingPercentEncoding];//在url中尋找自定義協(xié)議頭"objc://"if([requestStr hasPrefix:@"objc://"]) {// 以"://"為中心將url分割成兩部分,放進(jìn)數(shù)組arrNSArray*arr = [requestStr componentsSeparatedByString:@"://"];
NSLog(@"%@",arr);//取其后半段NSString*paramStr = arr[1];
NSLog(@"%@",paramStr);
//以":/"為標(biāo)識(shí)將后半段url分割成若干部分,放進(jìn)數(shù)組arr2,此時(shí)arr2[0]為空,arr2[1]為第一個(gè)傳參值,arr2[2]為第二個(gè)傳參值,以此類推NSArray*arr2 = [paramStr componentsSeparatedByString:@":/"];NSLog(@"%@",arr2);//取出參數(shù),進(jìn)行使用if(arr2.count) {NSLog(@"有參數(shù)");
[selfdoSomeThingWithParamA:arr2[1] andParamB:arr2[2]];
}else{NSLog(@"無(wú)參數(shù)");
}returnNO;
}returnYES;
}//對(duì)JS傳來(lái)的值進(jìn)行調(diào)用
- (void)doSomeThingWithParamA:(id)paramA andParamB:(id)paramB{NSLog(@"%@? ? %@", paramA, paramB);
}
該方法主要是通過(guò)截?cái)郩RL來(lái)獲取到參數(shù),需要JS那邊的配合度比較高,如果出現(xiàn)JS修改代碼或者結(jié)構(gòu),這OC這邊也要相應(yīng)的變化。
第二種:OC給JS傳值
使用場(chǎng)景:比如我點(diǎn)擊了網(wǎng)頁(yè)中的一個(gè)按鈕,需要告訴調(diào)用網(wǎng)頁(yè)的某個(gè)方法
同樣是在webView加載完畢時(shí)候添加JS代碼,其中alert則是JS那邊的方法名,里面的字符串則是要傳遞的值。
-(void)webViewDidFinishLoad:(UIWebView*)webView{
JSContext*content = [webViewvalueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
NSString* runJS =@"alert('OC成功調(diào)用了JavaScript的alert()方法!')";
[contentevaluateScript:runJS];
}
關(guān)于OC調(diào)用JS方法,再補(bǔ)充一下,這里需要一個(gè)橋接類
@protocol JSObjectProtocol
- (void)chooseAction:(NSString *test); ?//這個(gè)為你JS代碼里面的方法名,需要一樣
@end
@interface TestJSObject :NSObject
@property(nonatomic,copy)void(^chooseAction)(NSString *test); //block回調(diào)
@end
@implementation TestJSObject
- (void)chooseImage:(NSString *test) {
if(self.chooseImageBlock) {
self.chooseImageBlock(test);? //.m中實(shí)現(xiàn)回調(diào)
}
}
-(void)webViewDidFinishLoad:(UIWebView*)webView{
self.jsContext= [self.webvalueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
TestJSObject *testJO =[ TestJSObject new];
假設(shè)你的JS代碼中是這樣調(diào)用edit事件的,HealthTest.edit('14')
那么在大括號(hào)中應(yīng)該填@“HealthTest”,由這個(gè)類對(duì)象調(diào)用他的方法edit,這就是為什么剛才協(xié)議那里說(shuō)明需要跟JS的方法名一樣的原因了。
self.jsContext[@"HealthTest"]=testJO;
[test JOsetChooseSymptomBlock:^(NSString*ID) {
NSLog(@"%@",ID); ?//這里的ID就是JS里面?zhèn)鞒鰜?lái)的了,可以做你需要的業(yè)務(wù)邏輯了
}];
}
下一篇文章在仔細(xì)介紹WKView的傳值方式。