源碼請(qǐng)點(diǎn)擊github地址下載。
下面講述實(shí)現(xiàn)OC和JS的交互会通,它們相互調(diào)用称龙,其中需要寫一個(gè)靜態(tài)的HTML文件用于提供JS方法。
效果圖如下:
screen.png
一.OC調(diào)用JS:
不說閑話因篇,看代碼如下
- 需要先在js文件定義方法postStr供oc調(diào)用
function postStr(string) {
return 'I am the return parameter JS, and param ' + string;
}
- oc代碼只需一句即可調(diào)用
NSString *str = [self.webView stringByEvaluatingJavaScriptFromString:@"postStr('ocToJs')"];
//輸出str為I am the return parameter JS, and param ocToJs泞辐,正式j(luò)s中postStr方法的返回值。
需注意的是正確書寫@"postStr('ocToJs')"的格式惜犀,postStr為js方法铛碑,ocToJs是OC傳遞給JS的參數(shù)。
二.JS調(diào)用OC:
- 在h5頁(yè)面添加了了button元素虽界,用于觸發(fā)js方法jsCallOCClicked
<button onclick="jsCallOCClicked()">
<h1>jsCallOC</h1>
</button>
- 在js文件的jsCallOCClicked()方法中去調(diào)用OC的jsCallToOC()方法
function jsCallOCClicked() {
window.location.href = "objc://jsCallToOC#param#github地址#param#https://github.com/SoftProgramLX/OcAndJs";
}
說明:<br>
1.“objc://”為自定義的OC識(shí)別JS調(diào)用的標(biāo)識(shí)<br>
2.“jsCallToOC”為需調(diào)用的OC方法<br>
3.“#param#”為自定義的方法與參數(shù)或參數(shù)與參數(shù)的分隔符<br>
4.“github地址”為js傳遞給OC的第一個(gè)參數(shù)<br>
5.“https://github.com/SoftProgramLX/OcAndJs”為js傳遞給OC的第二個(gè)參數(shù)<br>
- 實(shí)現(xiàn)OC的jsCallToOC()方法
- (void)jsCallToOC:(NSArray *)params
{
dataArr = params;
alertV = [[UIAlertView alloc] initWithTitle:@"js已經(jīng)調(diào)用了OC方法" message:@"查看控制臺(tái)的信息汽烦,點(diǎn)擊取消會(huì)再觸發(fā)OC調(diào)用js" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];
alertV.tag = 9666;
[alertV show];
NSLog(@"js調(diào)用OC返回值:%@", params);
}
這里params[0]輸出是github地址,params[1]輸出是https://github.com/SoftProgramLX/OcAndJs
- 關(guān)鍵所在
目前JS調(diào)用OC的jsCallToOC()方法還不會(huì)觸發(fā)莉御,當(dāng)點(diǎn)擊h5頁(yè)面的按鈕時(shí)只會(huì)觸發(fā)OC的- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;這個(gè)方法撇吞。
需在這個(gè)方法里解析request參數(shù)的URL值俗冻,解析后path的值就是"objc://jsCallToOC#param#github地址#param#https://github.com/SoftProgramLX/OcAndJs",再繼續(xù)分解出里面的方法與參數(shù)牍颈,然后執(zhí)行[self performSelector:todoM withObject:params afterDelay:0];代碼才能觸發(fā)OC的jsCallToOC()方法迄薄。
代碼如下:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSString *path = [[request URL] absoluteString];
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 7.0) {
path = [path stringByRemovingPercentEncoding];
}else{
path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
if ([path hasPrefix:@"ios"]||[path hasPrefix:@"objc"]) {
NSString *method = [path substringFromIndex:@"objc://".length];
NSArray *sels = [method componentsSeparatedByString:@"#param#"];
SEL todoM;
if (sels.count>1) {
todoM = NSSelectorFromString([NSString stringWithFormat:@"%@:",sels[0]]);
NSMutableArray *params = [NSMutableArray array];
for (int i=1; i<sels.count; i++) {
[params addObject:sels[i]];
}
if ([self respondsToSelector:todoM]) {
[self performSelector:todoM withObject:params afterDelay:0];
}
}else if(sels.count==1){
todoM = NSSelectorFromString([NSString stringWithString:sels[0]]);
if ([self respondsToSelector:todoM]) {
[self performSelector:todoM withObject:nil afterDelay:0];
}
}
return NO;
}
return YES;
}
說明:<br>
這里判斷sels.count>1的目的是判斷有無(wú)傳參<br>
若無(wú)參數(shù)則定義方法- (void)jsCallToOC;<br>
若有參數(shù)則定義方法- (void)jsCallToOC:(NSArray *)params煮岁。
三.額外方法
- 禁止復(fù)制網(wǎng)頁(yè)文字
- (void)deletePrompt
{
[self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
[self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
}
- 用于js統(tǒng)計(jì)
- (void)jsStatistics
{
NSString *systemUserAgent = [self.webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
if (!([systemUserAgent rangeOfString:@"****-app-iphone Version/"].length > 0)) {
NSString *currentVersion = [NSBundle mainBundle].infoDictionary[(__bridge NSString *)kCFBundleVersionKey];
systemUserAgent = [systemUserAgent stringByAppendingFormat:@" ***-app-iphone Version/%@", currentVersion];
}
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:systemUserAgent, @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
}