美文网首页
OC和JS交互(一):协议拦截

OC和JS交互(一):协议拦截

作者: 上发条的树 | 来源:发表于2018-01-02 11:07 被阅读63次

协议拦截

通俗点理解,就是定义好一个协议,JS使用该协议来调用OC/Swift的方法,并且传值给OC/Swift。
大概的格式如下:

协议名称://方法名称?参数1=数值1&参数2=数值2

例如

wxx://sendTitle?title=标题&name=测试

其中wxx为约定好的协议名称,sendTitle为约定好的OC/Swift的方法名称,title=标题&name=测试为参数列表。当然,参数列表可以是不同的格式,对应着OC/Swift那边的解析方式也就不同。

协议例如的基本格式如下:

wxx://sendTitle?title=标题&name=测试

或者JSON格式:

wxx://sendTitle?{'title':'标题','name':'测试'}

当然如果参数很多,可以使用对象转JSON,再拼接进协议:

var titleObj = new Object();
titleObj.title = '苹果'
titleObj.name = '标题'
...
var jsonStr = JSON.stringify(titleObj);
"wxx://sendTitle?".concat(jsonStr)

既然有了协议,我们就可以使用协议。
假如以上拼接好的协议是叫protocol
可以这样使用:

location.href = protocol;

或者:

window.location.href = protocol;

还有就是这种写法(不知道跟前两者有何区别,或者有何优势,对JavaScript不太了解,后续再学习下。):

function loadURL(url) {
        var iFrame;
        iFrame = document.createElement("iframe");
        iFrame.setAttribute("src", url);
        iFrame.setAttribute("style", "display:none;");
        iFrame.setAttribute("height", "0px");
        iFrame.setAttribute("width", "0px");
        iFrame.setAttribute("frameborder", "0");
        document.body.appendChild(iFrame);
        // 发起请求后这个iFrame就没用了,所以把它从dom上移除掉
        iFrame.parentNode.removeChild(iFrame);
        iFrame = null;
    }

url就是传入的协议:

loadURL(protocol)

OC端的处理

对于协议的拦截,UIWebViewWKWebView需要在对应的回调中去拦截:

UIWebView

#pragma mark -UIWebViewDelegate
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    NSURL *url = request.URL;
    NSString *scheme = [url scheme];
    NSLog(@"%@",scheme);
    if ([scheme isEqualToString:@"wxx"]) {
        [self handleCustomAction: url];
        return NO;
    }
    return YES;
}

WKWebView

#pragma mark -WKNavigationDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    
    NSURL *url = navigationAction.request.URL;
    NSString *scheme = [url scheme];
    //拦截wxx协议
    if ([scheme isEqualToString:@"wxx"]) {
        [self handleCustomAction:url];
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
    }
    decisionHandler(WKNavigationActionPolicyAllow);
}

两者在写法上有些差异,但是道理是一样的。其中request.URLnavigationAction.request.URL就是我们在JS中定义的完整协议(包括协议名称,方法名称以及参数,如果有参数的话)。而[url scheme]就是协议名称,我们根据协议名称进行拦截:if ([scheme isEqualToString:@"wxx"])。而在handleCustomAction:方法中,我们可以根据方法名,来分别调用OC的不同方法:

- (void)handleCustomAction:(NSURL *)url{
    NSString *host = [url host];
    
    if ([host isEqualToString:@"sendTitle"]) {
        [self sendTitle:url];
    }
}

其中[url host]可以获取方法名称。最终我们在通过[url query]取出参数,做具体解析。
从上面我们可以总结,OC端获取协议、协议名称、方法名称和参数分别如下:

  • request.URL(UIWebView)
    navigationAction.request.URL(WKWebView)
  • [url scheme]
  • [url host]
  • [url query]

大致如图所示:


协议基本格式.png

特别注意:协议名称中如果含有大写字母,[url scheme]获取的协议名称都会被转换为小写

JS传给OC/Swift含有中文的乱码问题

一般来说,JS调用OC/Swift的方法,基本有以下两种情况:

  • 调用OC/Swift中原生的系统功能,如相机,相册。
  • 传值给OC/Swift使用。

通过[url query]取出参数,却发现,含有中文的时候,打印出来的string是乱码的,例如这样我的参数是

{"title":"标题"}
NSString *query = url.query;
//转为UTF-8格式的字符串
query = [query stringByRemovingPercentEncoding];

而OC端打印出来是

{"title":"æ ‡é¢˜"}

这个问题肯定是转码的问题,既然OC端使用这个stringByRemovingPercentEncoding是没错的。那么就是H5页面的问题了,最终发现,需要在<head>中增加这样一句,以此指定好使用的字符集:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8">

content-Type用于设定页面显示的字符集。

有关iOS的解码

下一篇:OC和JS交互(二):WKWebView之MessageHandler

相关文章

  • oc 与js 的原生交互

    参考 总评: oc 与js的交互,1.有原生的方式,oc 调js简单,js调oc 麻烦(协议拦截"实现的交互方式)...

  • OC和JS交互(一):协议拦截

    协议拦截 通俗点理解,就是定义好一个协议,JS使用该协议来调用OC/Swift的方法,并且传值给OC/Swift。...

  • iOS JS和原生交互(整理)

    WKWebView交互 1.JS调OC 方案1:主要是通过拦截URL,做协议字符匹配(如:js_native://...

  • iOS 的JS 和 OC 交互(二)

    iOS 的JS 和 OC 交互(一) 好吧 今天继续再来搞搞 这个 交互的问题 OC 怎样可以拦截到 JS 的调...

  • Cordova方法

    一,Js与oc交互: 方法1,拦截请求;方法2,拦截页面跳转 方法1,js使用 XMLHttpRequest 发起...

  • OC与JS交互总结

    OC与JS交互的4种方式 1 UIWebView 1.1 直接URL拦截 JS调OC shouldStartLoa...

  • iOS与JS交互之WKWebView-协议拦截

    级别:★★☆☆☆标签:「iOS与JS交互」「WKWebView与JS交互」「WKWebView拦截协议」作者: X...

  • iOS与JS交互之UIWebView-协议拦截

    级别:★★☆☆☆标签:「iOS与JS交互」「UIWebView与JS交互」「UIWebView拦截协议」作者: X...

  • WebView与JS的几种交互

    最近整理了一下原生与H5之间的交互方式,简单的做个总结。OC端与JS的交互,大致有这几种:拦截协议、JavaScr...

  • JS与OC的交互(iOS7前后对比)

    16/07/20 JS与OC的交互 iOS7之前 通过拦截URL的方式实现交互 在iOS7之前,实现js与oc的交...

网友评论

      本文标题:OC和JS交互(一):协议拦截

      本文链接:https://www.haomeiwen.com/subject/ubzugxtx.html