简单整理了下在ios编译环境下,oc与js相互调用通过UIWebview拦截url,达到实现效果。
1.创建本地html文件
html文件.png
2.创建UIWebview
self.webView = [[UIWebView alloc] initWithFrame:self.view.frame];
self.webView.delegate = self;
NSURL *htmlURL = [[NSBundle mainBundle] URLForResource:@"index.html" withExtension:nil];
// NSURL *htmlURL = [NSURL URLWithString:@"http://www.baidu.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:htmlURL];
// 如果不想要webView 的回弹效果
self.webView.scrollView.bounces = NO;
// UIWebView 滚动的比较慢,这里设置为正常速度
self.webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
[self.webView loadRequest:request];
[self.view addSubview:self.webView];
3.通过UIWebViewDelegate代理方法拦截Url
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *URL = request.URL; // haleyaction://scanClick
NSString *scheme = [URL scheme]; // haleyaction
if ([scheme isEqualToString:@"haleyaction"]) {
[self handleCustomAction:URL];
return NO;
}
return YES;
}
通过判断scheme判断实现不同的方法
- (void)handleCustomAction:(NSURL *)URL
{
NSString *host = [URL host];
if ([host isEqualToString:@"scanClick"]) {
NSLog(@"扫一扫");
} else if ([host isEqualToString:@"shareClick"]) {
[self share:URL];
} else if ([host isEqualToString:@"getLocation"]) {
[self getLocation];
} else if ([host isEqualToString:@"setColor"]) {
[self changeBGColor:URL];
} else if ([host isEqualToString:@"payAction"]) {
[self payAction:URL];
} else if ([host isEqualToString:@"shake"]) {
[self shakeAction];
} else if ([host isEqualToString:@"goBack"]) {
[self goBack];
}
}
回调结果到js中
- (void)getLocation
{
// 获取位置信息
// 将结果返回给js
NSString *jsStr = [NSString stringWithFormat:@"setLocation('%@')",@"广东省深圳市南山区学府路XXXX号"];
[self.webView stringByEvaluatingJavaScriptFromString:jsStr];
}
在js中把参数传给OC
function shareClick() {
loadURL("haleyAction://shareClick?title=测试分享的标题&content=测试分享的内容&url=http://www.baidu.com");
}
获取传递过来的参数,通过相关重要参数分割,组成新的字典
- (void)share:(NSURL *)URL
{
// URL.query ===》 title=%E6%B5%8B%E8%AF%95%E5%88%86%E4%BA%AB%E7%9A%84%E6%A0%87%E9%A2%98&content=%E6%B5%8B%E8%AF%95%E5%88%86%E4%BA%AB%E7%9A%84%E5%86%85%E5%AE%B9&url=http://www.baidu.com
NSArray *params =[URL.query componentsSeparatedByString:@"&"];
/*
<__NSArrayM 0x60400044af80>(
title=%E6%B5%8B%E8%AF%95%E5%88%86%E4%BA%AB%E7%9A%84%E6%A0%87%E9%A2%98,
content=%E6%B5%8B%E8%AF%95%E5%88%86%E4%BA%AB%E7%9A%84%E5%86%85%E5%AE%B9,
url=http://www.baidu.com
)
*/
NSMutableDictionary *tempDic = [NSMutableDictionary dictionary];
for (NSString *paramStr in params) {
NSArray *dicArray = [paramStr componentsSeparatedByString:@"="];
if (dicArray.count > 1) {
NSString *decodeValue = [dicArray[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[tempDic setObject:decodeValue forKey:dicArray[0]];
/*
(lldb) po tempDic
{
content = "\U6d4b\U8bd5\U5206\U4eab\U7684\U5185\U5bb9";
title = "\U6d4b\U8bd5\U5206\U4eab\U7684\U6807\U9898";
url = "http://www.baidu.com";
}
*/
}
}
NSString *title = [tempDic objectForKey:@"title"];
NSString *content = [tempDic objectForKey:@"content"];
NSString *url = [tempDic objectForKey:@"url"];
// 在这里执行分享的操作
// 将分享结果返回给js 划重点
NSString *jsStr = [NSString stringWithFormat:@"shareResult('%@','%@','%@')",title,content,url];
[self.webView stringByEvaluatingJavaScriptFromString:jsStr];
}
OC调用JS方法
oc调用Js方法.png
在OC中的方法调用
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[webView stringByEvaluatingJavaScriptFromString:@"var arr = [3, 4, 'abc'];"];
}
实现效果
js与oc交互.gif
注意事项
如果回调执行的JS 方法带参数,而参数不是字符串时,不要加单引号,否则可能导致调用JS 方法失败。比如我这样的:
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:userProfile options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString *jsStr = [NSString stringWithFormat:@"loginResult('%@',%@)",type, jsonStr];
[_webView stringByEvaluatingJavaScriptFromString:jsStr];
如果第二个参数用单引号包起来,就会导致JS端的loginResult不会调用。
注意要点在oc中调用js中方法,方法名称和参数均要一一对应。