UIWebView中Objective-C与JavaScript交互

转载 2016年05月30日 17:30:39

UIWebView中Objective-C与JavaScript交互

image

现在越来越多的项目为了支持公司业务的发展而选择使用HTML5做一些功能,那么这样就会涉及到HTML5与原生Objective-C的交互,今天就聊聊HMTL与原生之间的相互调用问题。

概述

原生与Web页面的交互可以分为Objective-C执行JavaScript代码和Web页面(或JavaScript)执行Objective-C代码,前者相对非常简单,后面可以通过JavaScriptCore、拦截协议等方式实现,下面我将主要对这二种方式进行叙述。

Objective-C执行JavaScript代码

打开UIWebView的头文件我们可以发现有一个方法叫stringByEvaluatingJavaScriptFromString:,它就是Objective-C执行JavaScript代码的通路,并且要注意它的返回值是NSString,这个方法在平时非常实用,列举几个例子:

// 获取当前页面的title
NSString *title = [webview stringByEvaluatingJavaScriptFromString:@"document.title"];

// 获取当前页面的可高度
float offsetHeight = [[webview stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];

// 获取需要分享的类内
NSString *sharedDictionary = [webview stringByEvaluatingJavaScriptFromString:@"getSharedContent"];

JavaScript执行Objective-C代码

JavaScript执行Objective-C代码之前我就说过有二种方式,现在我分别来说说这二种方式。

1. 利用JavaScriptCore来执行Objective-C代码

iOS7之后苹果推出了JavaScriptCore这个框架,从而让Web页面和本地原生应用交互起来非常方便,而且使用此框架可以做到Android那边和iOS相对统一,web前端写一套代码就可以适配客户端的两个平台,从而减少了Web前端的工作量。

Web前端

在三端交互中,web前端要强势一些,一切传值、方法命名都按web前端开发人员来定义,让另外两端去做适配。在这里以调用分享为例来详细讲解,测试网页代码取名为shared.html,其代码内容如下:

shared.html代码内容

<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <title>js调用objective-c代码</title>
    <style type="text/css">
        #backButton { 
            display: inline-block;
            width:50px; height:30px;
        }
    </style>
</head>

<body>
    <button id="backButton">返回</button>
    <script type="text/javascript">

        var btn = document.getElementById('backButton');

        btn.addEventListener('click', function() {
           callBackObj.letsGoBack();
        });
    </script>
</body>
</html>
iOS

iOS这边根据前端定义的方法名来写代码,但是有些时候web前端会让我们定义,但是我们定义好之后他又要修改,这时候就会很烦啊。所以碰到三端交互的时候最好就是让web前端去定义方法名,iOS和Android根据web前端定义好的去写代码。JavaScriptCore中web页面调用原生应用的方法可以用Delegate或Block两种方法,此文以按Delegate讲解。

JavaScriptCore中类及协议:

JSContext:给JavaScript提供运行的上下文环境
JSValue:JavaScript和Objective-C数据和方法的桥梁
JSManagedValue:管理数据和方法的类
JSVirtualMachine:处理线程相关,使用较少
JSExport:这是一个协议,如果采用协议的方法交互,自己定义的协议必须遵守此协议

ViewController中的代码

- (void)webViewDidFinishLoad:(UIWebView *)webView {

    JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    [context setExceptionHandler:^(JSContext *ctx, JSValue *value) {
    NSLog(@"error: %@", value);
}];

    context[@"callBackObj"] = self;
}

- (void) letsGoBack {
    [self.navigationController popViewControllerAnimated:YES];
}

ViewController中的代码解释

看到上面的代码我们可以看到设置了context中的callBackObj为self,通过这样的设置js在使用callBackObj.letsGoBack时其实等价于在viewController中使用[self letsGoBack]。

运行效果如图所示

image

拦截协议

首先我说解释一下什么是协议,协议是共同计议的规定,是大家一起遵循的准则。拦截协议这个非常适合各个平台,不需要引入什么框架,只需要大家相互之间遵守协议就可以了。那么在我们团队中协议是怎么定义的呢?scheme://model/aciton?{参数1}={数值1}&{参数2}={数值2}&…,比如在金蛋中分享的协议会是:jindanlicai://active/shared?callback=result(‘%s’,‘%s’)&function=getContent()。其中,function的值是可以获取分享内容的JavaScript函数名称,callback的值是分享结束之后调用的方法来告知HTML5是否分享成功与失败状态。

web前端

home.html中的代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <div>
            <input type="button" value="分享" onclick="share()">
        </div>

        <script>
        function share() {
            window.location.href = 'jindanlicai://active/shared?callback=result('%s','%s')&function=getContent()';
        }
        </script>
    </body>
</html>

home.html中的代码解释

通过点击分享按钮将会调用JavaStript中的share(),window.location.href这里是改变主窗口的指向从而马上发出一个链接为‘jindanlicai://active/shared?callback=result(‘%s’,‘%s’)&function=getContent()’请求,而在iOS方法中我们要拦截这个请求,根据URL请求内容去判断Web页面想要原生做的事情,从而实现web页面和本地应用之间的交互。

iOS

iOS对应的代码

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSString *url = request.URL.absoluteString;
    if ([[request.URL scheme] isEqualToString:@"jindanlicai"]) {
        [JDOpenURL handlerURL:request.URL context:self];
        return NO;
    }
    return YES;
}

iOS对应的代码的解释

在webView的代理方法中去拦截URL的scheme为自定义jindanlicai协议,调用原生提前约定好的方法,并且返回值为NO来阻止此链接的跳转。

总结

随着手机硬件的配置越来越强大和HTML5的兴起,一个App完全可以由web页面来写。现在在我们公司已经有很多的App已经完全是这么干了,iOS和Android只是给这个App套一个壳并通过一些协议去实现一些本地逻辑。协议是一个非常不错的方法,在这我推荐使用协议去做这样的事,当前提前是你要非常理解协议。如果有人喜欢协议,WebViewJavaScriptBridge是一个不错的第三库。

iOS 开发 Object-C和JavaScript交互详解之OC与JS交互在UIWebView中使用

1.需求分析在浏览器终端中写js代码删除网页中不需要的元素 2.OC调用JS需要实现的代理方法网页加载完成时调用的代理方法 当网页加载完成之后,通过OC的方法调用JS的代码,删除网页展示时不需要的内...
  • kuangdacaikuang
  • kuangdacaikuang
  • 2016年11月24日 09:06
  • 708

IOS开发 - UIWebView(用法全面介绍,含最全的JS交互)

前两天我写了一套关于JS与OC交互的三种方法的文章,但是发现自己对UIWebView理解的还是比较浅,一直认为只能简单的当一个webView来使用,具体很多细节都忽略,如果想看我之前UIWebView...
  • sheng_bin
  • sheng_bin
  • 2016年11月10日 22:36
  • 3661

iOS开发,UIWebview与H5之间的交互

将HTML页面加载到UIWebview控件中: A:本地加载: NSString *webPath = [[NSBundle  mainBundle]pathForResource:@“Hel...
  • sszTechnology
  • sszTechnology
  • 2016年05月26日 14:57
  • 2608

iOS开发--UIWebview与H5之间的交互

随着互联网产业的发展,在移动开发的过程中原生与H5的混合开发在移动开发中占据着越来越重要的地位。 下面介绍开发中的一些心得 1: 将HTML页面加载到UIWebview控件中: A:本...
  • qq_25475307
  • qq_25475307
  • 2015年12月01日 15:58
  • 2026

UIWebView - 使用方法总结

现在对于混合式移动端开发越来越流行,因为开发成本上、速度上都比传统的APP开发要好,混合式开发是传统模式与PC网页端相结合的模式。那么提到了 APP的混合模式开发,在Android开发中有WebVie...
  • CatStarXcode
  • CatStarXcode
  • 2016年04月21日 18:43
  • 2501

UIWebView与javascript交互三通过OC页面来改变html页面上的值

有一件事要说一下哦, 《UIWebView与javascript交互一》这篇博客被几个网站给转载了,很开心,但是开心之余有一点觉得要说一下,大家转载别人的文章的时候记得说明一下转载的出处,有两方面的原...
  • HHL110120
  • HHL110120
  • 2015年04月23日 15:34
  • 1337

ios与javascript的交互,适合刚接触电商ios与html5混编的朋友,(ios自学笔记)

在写 JavaScript 的时候,可以使用一个叫做 window 的对象,像是我们想要从现在的网页跳到另外一个网页的时候,就会去修改 window.location.href 的位置;在我们的 Ob...
  • wangyang6275
  • wangyang6275
  • 2015年07月15日 09:10
  • 1956

UIWebView与JavaScript简单交互操作

http://mobile.51cto.com/iphone-280965.htm iOS开发之Objective-C与JavaScript交互操作是本文要介绍的内容,主要主要是讲解了strin...
  • u010486174
  • u010486174
  • 2013年11月19日 09:52
  • 933

Objective-C与JavaScript交互的那些事

Objective-C与JavaScript交互
  • y2888886
  • y2888886
  • 2016年01月18日 15:03
  • 208

Objective-C与JavaScript交互的那些事

最近公司的运营瞎搞了个活动,其活动要服务端提供数据支持,web前端在微信公众账号内作为主要的运营阵地,而iOS、Android要提供相应的入口及页面进行配合。一个活动,动用了各个端的程序猿。而在这里面...
  • luobo140716
  • luobo140716
  • 2016年03月09日 19:54
  • 206
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UIWebView中Objective-C与JavaScript交互
举报原因:
原因补充:

(最多只允许输入30个字)