ios UIWebView与JS交互

工作中遇到的JS交互问题,稍微整理一下,留下来以备以后查用

JavaScriptCore.framework提供两种方法交互方法,
一种是基于block的交互,
一种是基于协议的交互

0.导入JavaScriptCore.framework(就是在building phases里添加库)

基于协议实现的JS与webView交互

1.定义协议,示例代码如下:

//  ZSJSDelegate.h

#import <JavaScriptCore/JavaScriptCore.h>

@protocol ZSJSDelegate <JSExport>
//JS从iOS获取数据
- (NSString *)postInfoFromWebView;
//iOS从JS获取数据
- (void)postInfoFromJS:(NSString *)info;
//iOS从JS获取数据,多参数拼接的情况
- (void)postNameFromJS:(NSString *)name andInfo:(NSString *)info;
@end

2.创建交互对象,遵守上述协议,实现协议方法,示例代码如下:

//  ZSJSObject.h
#import <Foundation/Foundation.h>
#import "ZSJSDelegate.h"
@interface ZSJSObject : NSObject
@end

//  ZSJSObject.m
#import "ZSJSObject.h"

@interface ZSJSObject ()<ZSJSDelegate>
@end
@implementation ZSJSObject

- (NSString *)postInfoFromWebView
{
    return @"infoForm_iOS";
}

- (void)postInfoFromJS:(NSString *)info
{
    NSLog(@"info:%@", info);
}

- (void)postNameFromJS:(NSString *)name andInfo:(NSString *)info
{
    NSLog(@"name:%@, info:%@", name, info);
}

@end

3.在webView中实现交互,示例代码如下:

//  ViewController.m

#import "ViewController.h"
#import "ZSJSObject.h"

@interface ViewController ()<UIWebViewDelegate>
@end

@implementation ViewController
{
    UIWebView *_webView;
    JSContext *_context;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self createWebView];
}

- (void)createWebView
{
    _webView = [[UIWebView alloc]initWithFrame:self.view.bounds];
    [self.view addSubview:_webView];
    _webView.backgroundColor = [UIColor lightGrayColor];
    _webView.delegate = self;

    NSURL *url = [NSURL URLWithString:@"https://www.baidu.com/"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [_webView loadRequest:request];

    //为什么这么写,我也不懂,希望有大神解惑
    _context = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    _context[@"jsObject"] = [[ZSJSObject alloc]init];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    //网页加载完成之后两秒钟,进行JS测试
    [self performSelector:@selector(testJS) withObject:nil afterDelay:2.0f];
}

//测试交互,手动写三个JS语句进行调用协议定义的方法
- (void)testJS
{
    //JS从iOS获取数据,通过返回值将数据传道JS
    [_context evaluateScript:@"alert(jsObject.postInfoFromWebView());"];
    //本地从JS获取数据,通过参数将数据传递到iOS
    [_context evaluateScript:@"jsObject.postInfoFromJS('infoFromJS');"];
    //多个参数拼接的规则:第二个参数名大写首字母
    [_context evaluateScript:@"jsObject.postNameFromJSAndInfo('nameFromJS','info');"];
}

基于block实现的JS与iOS交互

【注意】:比协议实现的步骤简单,但是容易出现控制器无法释放的问题,对内存要求不高的可以忽略
直接上示例代码:

//  JSWithBlockViewController.m

#import "JSWithBlockViewController.h"

#import <JavaScriptCore/JavaScriptCore.h>

@interface JSWithBlockViewController ()<UIWebViewDelegate>

@end

@implementation JSWithBlockViewController
{
    UIWebView *_webView;
    JSContext *_context;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self createWebView];
}

- (void)createWebView
{
    _webView = [[UIWebView alloc]initWithFrame:self.view.bounds];
    [self.view addSubview:_webView];
    _webView.backgroundColor = [UIColor lightGrayColor];
    _webView.delegate = self;

    NSURL *url = [NSURL URLWithString:@"https://www.baidu.com/"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [_webView loadRequest:request];

    //为什么这么写,我也不懂,希望有大神解惑
    _context = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

    //JS从iOS获取数据的实现
    _context[@"postInfoFromWebView"] = ^() {
        return @"infoFrom_iOS(block)";
    };
    //iOS从JS获取数据的实现
    _context[@"postInfoFromJS"] = ^() {
        NSArray *args = [JSContext currentArguments];
        for (JSValue *jsVal in args) {
            NSString *str = jsVal.toString;
            NSLog(@"arg:%@", str);
        }
    };
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    //网页加载完成之后两秒钟,进行JS测试
    [self performSelector:@selector(testJS) withObject:nil afterDelay:2.0f];
}

//测试交互,手动写三个JS语句进行调用协议定义的方法
- (void)testJS
{
    //JS从iOS获取数据,通过返回值将数据传到JS
    [_context evaluateScript:@"alert(postInfoFromWebView());"];
    //本地从JS获取数据,通过参数将数据传递到iOS
    [_context evaluateScript:@"postInfoFromJS('infoFromJS');"];
    [_context evaluateScript:@"postInfoFromJS('nameFromJS','info');"];

}

基本上就这些,有什么不妥的可以联系我。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值