OC与JS互相调用

最近项目中要用到html5来实现,涉及到OC调用JS,以及JS调用OC的方法,这里把遇到的问题以及实现方法介绍一下。

//
//  ViewController.h
//  OC_And_JS
//
//  Created by 张杰 on 15/7/9.
//  Copyright © 2015年 张杰. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UIWebViewDelegate>

@property (weak, nonatomic) IBOutlet UIButton *oc_call_js_no_params;
@property (weak, nonatomic) IBOutlet UIButton *oc_call_js_has_params;
@property (weak, nonatomic) IBOutlet UIWebView *mWebView;
@property (weak, nonatomic) IBOutlet UILabel *js_call_oc_show;

- (IBAction)ocCallJsNoParams:(id)sender;
- (IBAction)ocCallJsHasParams:(id)sender;

@end
//
//  ViewController.m
//  OC_And_JS
//
//  Created by 张杰 on 15/7/9.
//  Copyright © 2015年 张杰. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    _mWebView.delegate = self;

    //打开URL
    NSString *path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
    [self.mWebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath: path]]];
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    NSString *urlstr = request.URL.absoluteString;
    NSRange range = [urlstr rangeOfString:@"ios://jwzhangjie"];
    if (range.length!=0) {
        _js_call_oc_show.text = [NSString stringWithFormat:@"请访问地址:%@", urlstr];
    }
    return YES;
}

-(void)webView:(nonnull UIWebView *)webView didFailLoadWithError:(nullable NSError *)error{
    NSLog(@"加载失败");
}

-(void)webViewDidStartLoad:(nonnull UIWebView *)webView{
    NSLog(@"开始加载");
}

-(void)webViewDidFinishLoad:(nonnull UIWebView *)webView{
    NSLog(@"开始结束");
//    对于调用js的时候最好这个方法里面或者之后
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)ocCallJsNoParams:(id)sender {
    NSString *js = [NSString stringWithFormat:@"ocCallJsNoParamsFunction();"];
    [self.mWebView stringByEvaluatingJavaScriptFromString:js];
}

- (IBAction)ocCallJsHasParams:(id)sender {
    NSString *js = [NSString stringWithFormat:@"ocCallJsHasParamsFunction(‘%@‘,‘%@‘);",@"jwzhangjie",@"http://jwzhangjie.cn"];
    [self.mWebView stringByEvaluatingJavaScriptFromString:js];
}
@end

function ocCallJsNoParamsFunction()
{
    alert("OC调用JS中的无参方法");
    var e = document.getElementById("js_shouw_text");
    e.options.add(new Option("OC调用JS中的无参方法", 2));
}

function ocCallJsHasParamsFunction(name, url)
{
    alert(name+"的博客地址为:"+url);
    var e = document.getElementById("js_shouw_text");
    e.options.add(new Option("OC调用JS中的有参方法", 2));
}

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>OC与JS互相调用</title>
</head>
<body>
    <div >
        <select id="js_shouw_text">
            <option>
                展示OC调用JS无参数
            </option>
        </select>
    </div>
    <div>
        <BR/>
        <input type="button" value="JS调用OC方法" onclick="js_call_oc()"/>
    </div>
    <!--  这里要清楚,虽然test.js跟index.html不同及目录,实际安装到程序里面后,是在同级目录的,所以这里src不能加目录,同样css也是一样的  -->
    <script type="text/javascript" src="test.js" charset="UTF-8"></script>
    <script type="text/javascript">
        function js_call_oc()
        {
            var iFrame;
            iFrame = document.createElement("iframe");
            iFrame.setAttribute("src", "ios://jwzhangjie");
            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;
        }

    </script>
</body>

</html>

规避1:对于OC去调用JS内容最好在webViewDidFinishLoad方法里或者之后

规避2:在html里面引用js或者css的时候src不要带有路径,因为安装后文件都在同级目录下面

规避3:OC调用JS的规范

 NSString *js = [NSString stringWithFormat:@"ocCallJsHasParamsFunction(‘%@‘,‘%@‘);",@"jwzhangjie",@"http://jwzhangjie.cn"];
    [self.mWebView stringByEvaluatingJavaScriptFromString:js];

规避4:JS调用OC,这里通过html里面发送一个请求,然后在ios中使用shouldStartLoadWithRequest拦截请求,根据请求url的不同进行处理。

 function js_call_oc()
        {
            var iFrame;
            iFrame = document.createElement("iframe");
            iFrame.setAttribute("src", "ios://jwzhangjie");
            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;
        }

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    NSString *urlstr = request.URL.absoluteString;
    NSRange range = [urlstr rangeOfString:@"ios://jwzhangjie"];
    if (range.length!=0) {
        _js_call_oc_show.text = [NSString stringWithFormat:@"请访问地址:%@", urlstr];
    }
    return YES;
}

源码地址:

http://jwzhangjie.cn/forum.php?mod=viewthread&tid=3&page=1&extra=#pid3

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 20:12:33

OC与JS互相调用的相关文章

关于混合开发,oc与js互相通信的方法总结:

最近做公司的几个项目,主要以为h5为主,不能实现的功能用oc来写,这样就经常牵扯到oc调用js,或者js调用oc.先插嘴一句,对于目前而言,我对H5包装下的app的用户体验是极其的不满,真的没法和原生比较.对注重用户体验的公司还是比较倾向与混合开发. 根据个人长期摸索,和开发踩过的坑,在这稍微总结一下下..网上有的基本都很零散,对于开发在使用还需要具体根据项目情况来使用. oc与js互相调用目前我知道的时主要有4种直接的方式: 1. 苹果的javascriptcore.framework框架;

WebViewJavascriptBridge源码探究--看OC和JS交互过程

今天把实现OC代码和JS代码交互的第三方库WebViewJavascriptBridge源码看了下,oc调用js方法我们是知道的,系统提供了stringByEvaluatingJavaScriptFromString函数 .现在主要是了解js是如何调用oc方法的,分享下探究过程. 源码不多,就一个头文件WebViewJavascriptBridge.h和实现文件WebViewJavascriptBridge.m, 和一个js文件,实现在js那边可以调用oc方法,也可以在oc里面调用js方法. 先

【cocos2d-js官方文档】二十三、如何在IOS平台上使用js直接调用OC方法

在Cocos2d-JS v3.0 RC2中,与Android上js调用Java一样,Cocos2d-JS也提供了在iOS和Mac上js直接调用Objective-C的方法,示例代码如下: var ojb = jsb.reflection.callStaticMethod(className, methodNmae, arg1, arg2, .....); 在jsb.reflection.callStaticMethod方法中,我们通过传入OC的类名,方法名,参数就可以直接调用OC的静态方法,并且

实现OC与JS的交互

oc-->js  stringByEvaluatingJavaScriptFromString,其参数是一NSString 字符串内容是js代码(这又可以是一个js函数.一句js代码或他们的组合),当js函数有返回值或一句js代码有值返回可通过stringByEvaluatingJavaScriptFromString的返回值获取. js-->oc 利用webView的重定向原理(即重新在js中指定document.location的值,此为一url),只要在这个url字符串中按自定义的规则指

OC与JS的交互详解

事情的起因还是因为项目需求驱动.折腾了两天,由于之前没有UIWebView与JS交互的经历,并且觉得这次在功能上有一定的创造性,特此留下一点文字,方便日后回顾. 我要实现这样一个需求:按照本地的CSS文件展示一串网络获取的带HTML格式的只有body部分的文本,需要自己拼写完整的HTML.除此之外,还需要禁用获取的HTML文本中自带的 < img > 标签自动加载,并把下载图片的操作放在native端来处理,并通过JS将图片在Cache中的地址返回给UIWebview. 之所以要把图片操作放在

[转]OC与JS的交互详解

http://www.cnblogs.com/wenxp2006/p/4777937.html 事情的起因还是因为项目需求驱动.折腾了两天,由于之前没有UIWebView与JS交互的经历,并且觉得这次在功能上有一定的创造性,特此留下一点文字,方便日后回顾. 我要实现这样一个需求:按照本地的CSS文件展示一串网络获取的带HTML格式的只有body部分的文本,需要自己拼写完整的HTML.除此之外,还需要禁用获取的HTML文本中自带的 < img > 标签自动加载,并把下载图片的操作放在native

OC和JS的交互---JavaScriptCore

JavaScriptCore的简单介绍 JavaScriptCore是iOS7提供的原生框架,可以让Objective-C和JavaScript提供简单直接的交互. JavaScriptCore的使用 导入JavaScriptCore.framework 在需要使用的类中引入头文件 #import <JavaScriptCore/JavaScriptCore.h> 点开头文件,我们可以看到 #import "JSContext.h" #import "JSValu

OC与JS混合开发

随着iOS开发的成本增大,越来越多的公司开始使用html5混合开发软件了,因为使用原生的开发花费的成本跟时间都很大,而使用html5来搭建界面会方便很多,效率相对而言也提高了.虽然使用UIWebView实现的交互效果与原生效果相比还是会大打折扣,这类界面通常没有复杂的交互效果,所以现在主流应用大多采用混合开发.花了几天时间,把JS的基础全部看了一遍,又研究了一下巧神的书,写了一个iOS7以前的JS与OC混合开发的demo. 既然是html5页面搭建的布局,那么肯定是得有html5页面的,所以首先

通过WebViewJavascriptBridge实现OC与JS交互

在.m方法当中,申明一个WebViewJavascriptBridge属性: 1 @interface ExampleAppViewController () 2 @property WebViewJavascriptBridge* bridge; 3 @end 4 5 @implementation ExampleAppViewController 6 7 8 - (void)viewDidLoad { 9 10 11 UIWebView* webView = [[UIWebView allo