iOS中JS与原生OC互相调用之问题总结一
来源:互联网 发布:6人游定制旅行怎样知乎 编辑:程序博客网 时间:2024/05/22 09:05
近期由于工作和个人的闲置没有及时的更新博客,为此对各位同学表示抱歉,那么废话不多说,今天我们就聊聊那些在iOS中JS与原生OC互相调用,直接上代码资料~
#pragma mark - JS中的一些细节
1> JS中自定义的URL,在被拦截到的时候url scheme会全部转成小写!
2> html中需要设置编码,否则中文参数可能会出现编码问题!
3> JS打开一个iFrame的方式替代直接用document.location的方式,以避免多次请求,被替换覆盖的问题!
#warning - stringByEvaluatingJavaScriptFromString方法注意
stringByEvaluatingJavaScriptFromString是一个同步的方法,使用它执行JS方法时,如果JS方法比较耗的时候,会造成界面卡顿!尤其是js弹出alert的时候。alert也会阻塞界面,等待用户响应,而stringByEvaluatingJavaScriptFromString又会等待js执行完毕返回。这就造成了死锁。官方推荐使用WKWebView的evaluateJavaScript:completionHandler:代替这个方法。
其实我们也有另外一种方式,自定义一个延迟执行alert的方法来防止阻塞,然后我们调用自定义的alert方法。同理,耗时较长的js方法也可以放到setTimeout中。
function asyncAlert(content)
{
setTimeout(function(){
alert(content);
},1);
}
#pragma mark -UIWebView拦截URL总结
loadURL
方法,而不直接使用window.location.href
?window.location.href
加载网页的同时,调用window.location.href
去调用OC原生方法,会导致加载网页的操window.location.href
执行两次OC原生调用,也有可能导致第一次的操作被取消掉。所以我们使用自定义的loadURL
,来避免这个问题。loadURL
的实现可以参考关于UIWebView和PhoneGap一文。2> 为什么loadURL中的链接,要规范使用统一的scheme?
ctionType
)来区分是调用原生的方法还是正常的网页跳转。然后根据host(即//后的部分getLocation
)来区分执行什么操作。asyncAlert
方法?stringByEvaluatingJavaScriptFromString
是一个同步方法,会等待js 方法执行完成,而弹出setTimeout
的function
中。#pragma mark - 代码示例
#pragma mark - UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:
(UIWebViewNavigationType)navigationType {
NSURL *URL = request.URL;NSString *scheme = [URL scheme];
if ([schemeisEqualToString:@"haleyaction"]) {
[self handleCustomAction:URL];
returnNO;
}
returnYES;
}
这里通过scheme,来拦截掉自定义的URL就非常容易了,如果不同的方法使用不同的scheme,那么判断起来就非常的麻烦。那么直接代码示例:
#pragma mark - 拦截URL调OC原生的方法
- (void)handleCustomAction:(NSURL *)URL {
NSString *host = [URLhost];
if ([hostisEqualToString:@"scan"]) {
} elseif ([hostisEqualToString:@"share"]) {
[self share:URL];
} elseif ([hostisEqualToString:@"getLocation"]) {
[self getLocation];
} elseif ([hostisEqualToString:@"pay"]) {
[self payAction:URL];
} elseif ([hostisEqualToString:@"shake"]) {
[self shakeAction];
} elseif ([hostisEqualToString:@"back"]) {
[self goBack];
}
}
#pragma mark - 如何将结果回调到JS中
- (void)getLocation
{
// 获取位置信息
// 将结果返回给js
NSString *jsStr = [NSStringstringWithFormat:@"setLocation('%@')",@"广东省深圳市宝安区西乡街道XXXX号"];
[self.webView stringByEvaluatingJavaScriptFromString:jsStr];
}
当然有时候我们在JS中调用OC方法的时候,也需要传参数到OC中,怎么传呢?就像一个get请求一样,把参数拼接在后面就行:
function share() {
loadURL("haleyAction://shareClick?title=测试标题&content=测试内容&url=http://www.baidu.com");
}
那么如何获取到这些参数呢?所有的参数都在URL的query中,先通过&将字符串拆分,在通过=把参数拆分成key和value示例代码:
- (void)share:(NSURL *)URL
{
NSArray *params =[URL.query componentsSeparatedByString:@"&"];
NSMutableDictionary *tempDic = [NSMutableDictionary dictionary];
for (NSString *paramStrin params) {
NSArray *dicArray = [paramStr componentsSeparatedByString:@"="];
if (dicArray.count >1) {
NSString *decodeValue = [dicArray[1]
stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[tempDic setObject:decodeValue forKey:dicArray[0]];
}
}
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];
}
#pragma mark - OC调用JS方法
如果回调执行的JS方法带参数,而参数不是字符串时,不要加单引号,否则可能导致调用JS方法失败。
- iOS中JS与原生OC互相调用之问题总结一
- iOS中JS与原生OC互相调用之问题总结二
- iOS中JS与原生OC互相调用之JavaScriptCore
- iOS下JS与原生OC互相调用(总结)
- iOS下JS与原生OC互相调用(总结)
- iOS下JS与原生OC互相调用(总结)
- iOS下JS与原生OC互相调用(总结)
- iOS下JS与原生OC互相调用(总结)
- iOS下JS与原生OC互相调用
- iOS下JS与原生OC互相调用
- iOS下JS与原生OC互相调用
- iOS下JS与原生OC互相调用
- iOS下JS与原生OC互相调用
- iOS下JS与原生OC互相调用
- IOS中OC与JS互相调用
- JS与原生OC互相调用方法
- JS与原生OC互相调用
- [iOS js与oc原生互相调用] js调用oc的两种方式
- SpringMVC集成mongodb
- mysql的事务
- Spark调优: 基础篇
- iOS 精美过度动画源码、网络音乐播放器源码、雷达图源码等
- 百度api获取用户位置
- iOS中JS与原生OC互相调用之问题总结一
- Android单元测试-Mockito的使用
- JavaScript Java
- 01——mock
- 笔记--jstl标签
- mysql_connect(): Headers and client library minor version mismatch. Headers:
- Ubuntu安装faster-rcnn编译caffe版本不兼容问题
- FastDFS与Springboot集成
- 浅析WPF中MVVM模式下命令与委托的关系