iOS 原生与JavaScript的交互

UIWebView(苹果已经弃用,长传ipa时会禁止,改用)

  • UIWebView使用的基本步骤:
  • 初始化UIWebView
	//web文件可以是本地也可以是网址,区别只是请求地址不同,交互都一样
    NSUrl *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@", self.webUrlStr]];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];
    self.webView.delegate = self;
  • 遵守UIWebViewDelegate协议
  • 读取UIWebView的内容
- (void)webViewDidFinishLoad:(UIWebView *)webView{
	//获取JS代码的执行环境/上下文/作用域
    self.context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];//固定的
    // 以 JSExport 协议关联 native 的方法
    self.context[@"native"] = self;
    //打印异常,由于JS的异常信息是不会在OC中被直接打印的,所以我们在这里添加打印异常信息,
    self.context.exceptionHandler = ^(JSContext *context, JSValue *exception) {
        context.exception = exception;
    };
  • 导入框架<JavaScriptCore/JavaScriptCore.h>
  • 自定义协议,自定义的协议遵守< JSExport >协议
  • 自定义协议里面写原生与JS交互的方法名
//原生调用web
JSExportAs(sendRequest, - (void)sendRequest:(NSString *)code);
JSExportAs(sendData, - (void)send:(NSString *)type WithDataParameter:(BOOL)args);
//其中JSExportAs是一个宏定义,用一个自定义的方法名代替js里面的方法名,比如原生里面调用-(void)sendRequest:(NSString *)code)这个方法就是间接调用了js里的window.TellNative.sendRequest(code)方法
#define sendRequest(code)  window.TellNative.sendRequest(code)
#define sendData(type, args) window.TellNative.sendData(type, args)

//web调用原生
- (void)finishBlockly;
- (void)ShakeDetector;
- (void)SensorDetector;
  • 原生向js里面传递参数,比如在- (void)sendRequest:(NSString *)code这个方法里面调用
- (void)sendRequest:(NSString *)code {
	JSValue *jsParam = self.context[@“callback4DataStore”];//web里面的方法名callback4DataStore
	NSLog(@"-------%@", jsParam);
	NSString *str1 = @“query”;
	NSString *str2 = @1;
	NSString *str3 = @0;
	
	//给web传的参数,没有传nil
	[jsParam callWithArguments:@[str1,str2,str3]];
	[jsParam callWithArguments:@[str1,str3]];
	//还可以通过JSContext的evaluateScript方法传递
	[self.context evaluateScript:[NSString stringWithFormat:@"约定的方法名(@"native")('参数1', '参数2')"]];
	
	//另一种方式
	NSString *jsString = [NSString stringWithFormat:@"约定的方法名(@"native")('参数1', '参数2')"];
	[self.webView stringByEvaluatingJavaScriptFromString:jsString];
	//UIWebView的-stringByEvaluatingJavaScriptFromString:方法可以执行JS代码。但只有在整个webView加载完成之后调用此方法才会有响应
}

  • 总结

1、UIWebView协议拦截方式

  • JS调用iOS
#pragma mark - UIWebViewDelegate
//! UIWebView在每次加载请求前会调用此方法来确认是否加载此请求
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if ([request.URL.scheme caseInsensitiveCompare:@"native"] == NSOrderedSame) {
        return NO;
    }
    return YES;
}
  • 用safari浏览器调试web

首先打开模拟器或者真机设置中"Safari浏览器"→"高级"→"Web检查器"的开关
打开Safari浏览器—>打开系统偏好设置—>“高级”—>勾选"在菜单栏中显示"开发"菜单".
真机连接上数据线.或者开启模拟器就能在菜单栏"开发"选项中找到我们的设备或者是模拟器。
进入对应的WebView页面即可进行调试

WKWebView

WKScriptMessageHandler协议方式

  • JS调用iOS
    1、 导入WebKit框架头文件:#import <WebKit/WebKit.h>
    2、遵守WKScriptMessageHandler协议
    3、 //! 为userContentController添加ScriptMessageHandler,并指明name
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
[userContentController addScriptMessageHandler:self name:@"jsToOc"];

4、//! 使用添加了ScriptMessageHandler的userContentController配置configuration

WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = userContentController;

5、 //! 使用configuration对象初始化webView

_webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration];

6、接收消息时的代理

//! WKWebView收到ScriptMessage时回调此方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {

    if ([message.name caseInsensitiveCompare:@"jsToOc"] == NSOrderedSame) {
    }
}

PS:[userContentController addScriptMessageHandler:self name:@“jsToOc”]会引起循环引用问题。一般来说,在合适的时机removeScriptMessageHandler可以解决此问题。比如:在-viewWillAppear:方法中执行add操作,在-viewWillDisappear:方法中执行remove操作。

  • iOS调用JS
    evaluateJavaScript:completionHandler:方法来实现
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值