OC与JS交互 初体会
第一篇博客,有点小紧张、小期待,会不会有人看?有也好,没有也罢,权当自己图个乐儿,记录近来学到的知识。闲话少说,进入正题!
OC与JS交互的方式:1、使用UIWebView通过拦截Request完成JS调取OC,通过stringByEvaluatingJavaScriptFromString注入JS函数或者取数据完成OC调取JS
2、使用WKWebView通过- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler完成OC调取JS,通过- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name拦截完成JS调取OC,还可以通过- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name完成JS调用OC
3、苹果有提供JavaScriptCore库,可以完成交互
4、第三方库WebViewJavascriptBridge
一、使用UIWebView
拦截Request完成JS调取OC
1 #pragma mark - UIWebViewDelegate 2 3 /** 4 这些都是JS响应的样式 5 UIWebViewNavigationTypeLinkClicked, 点击 6 UIWebViewNavigationTypeFormSubmitted, 提交 7 UIWebViewNavigationTypeBackForward, 返回 8 UIWebViewNavigationTypeReload, 刷新 9 UIWebViewNavigationTypeFormResubmitted, 重复提交 10 UIWebViewNavigationTypeOther 其他 11 12 */ 13 // 加载所有请求数据,以及控制是否加载 14 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ 15 16 NSLog(@"%@",request.URL.scheme); // 标识 我们自己协议 17 NSLog(@"%@",request.URL.host); // 方法名 18 NSLog(@"%@",request.URL.pathComponents); // 参数 19 20 // JS 调用OC 的原理就是 拦截URL 21 NSString *scheme = request.URL.scheme; 22 if ([scheme isEqualToString:@"custom"]) { 23 NSLog(@"来了,我们自定义的协议"); 24 25 NSArray *args = request.URL.pathComponents; 26 NSString *methodName = args[1]; 27 28 29 SEL methodSel = NSSelectorFromString(methodName); 30 if ([self respondsToSelector:methodSel]) { 31 32 [self performSelector:methodSel withObject:args[2]]; 33 34 } 35 36 return NO; 37 } 38 39 return YES; 40 }
通过stringByEvaluatingJavaScriptFromString注入JS函数或者取数据完成OC调取JS
// 加载完成 - (void)webViewDidFinishLoad:(UIWebView *)webView{//获取titleNSString *titlt = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];self.title = titlt;}//调用JS函数 NSString *result = [self.webView stringByEvaluatingJavaScriptFromString:@"showAlert('HELLO')"];
二、使用WKWebView
拦截Request
#pragma mark - WKNavigationDelegate - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {NSURL *URL = navigationAction.request.URL;NSString *scheme = [URL scheme];if ([scheme isEqualToString:@"tzedu"]) {NSString *host = [URL host];if ([host isEqualToString:@"jsCallOC"]) {NSMutableDictionary *temDict = [self decoderUrl:URL];NSString *username = [temDict objectForKey:@"username"];NSString *password = [temDict objectForKey:@"password"];NSLog(@"%@---%@",username,password);}else{NSLog(@"不明地址 %@",host);}decisionHandler(WKNavigationActionPolicyCancel);return;}decisionHandler(WKNavigationActionPolicyAllow); }- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{self.title = webView.title; }
MessageHandler:
- (void)viewWillAppear:(BOOL)animated{[super viewWillAppear:animated];[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"messgaeOC"]; }- (void)viewWillDisappear:(BOOL)animated{[super viewWillDisappear:animated];//注意循环引用[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"messgaeOC"]; } #pragma mark - WKScriptMessageHandler- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{NSLog(@"message == %@ --- %@",message.name,message.body);}
OC调取JS:
NSString *jsStr2 = @"showAlert('messageHandle:OC-->JS')";[self.webView evaluateJavaScript:jsStr2 completionHandler:^(id _Nullable result, NSError * _Nullable error) {NSLog(@"%@----%@",result, error);}];
三、JavaScriptCore
JSContext:给JavaScript提供运行的上下文环境JSValue:JavaScript和Objective-C数据和方法的桥梁JSManagedValue:管理数据和方法的类JSVirtualMachine:处理线程相关,使用较少JSExport:这是一个协议,如果采用协议的方法交互,自己定义的协议必须遵守此协议
- (void)webViewDidFinishLoad:(UIWebView *)webView{NSString *titlt = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];self.title = titlt;//JSContext就为其提供着运行环境 H5上下文JSContext *jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];self.jsContext = jsContext;__weak typeof(self) weakSelf = self;// 异常处理self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {context.exception = exception;NSLog(@"exception == %@",exception);NSLog(@"%@",context);};// 提供给JS全局变量[self.jsContext evaluateScript:@"var arr = [3, 'Hello', 'abc'];"];self.jsContext[@"showMessage"] = ^() {JSValue *thisValue = [JSContext currentThis];NSLog(@"thisValue = %@",thisValue);JSValue *cValue = [JSContext currentCallee];NSLog(@"cValue = %@",cValue);NSArray *args = [JSContext currentArguments];NSLog(@"来了:%@",args);NSDictionary *dict = @{@"name":@"cooci",@"age":@18};[[JSContext currentContext][@"ocCalljs"] callWithArguments:@[dict]];};// 因为是全局变量 可以直接获取JSValue *arrValue = self.jsContext[@"arr"];NSLog(@"arrValue == %@",arrValue);//纠正用法 // JSValue *value = [JSValue valueWithObject:@"test“ inContext:context]; // JSManagedValue *managedValue = [JSManagedValue managedValueWithValue:value andOwner:self]; self.jsContext[@"showDict"] = ^(JSValue *value) {//注意线程问题NSArray *args = [JSContext currentArguments];JSValue *dictValue = args[0];NSDictionary *dict = dictValue.toDictionary;NSLog(@"%@",dict);// 模拟用int num = [[arrValue.toArray objectAtIndex:0] intValue];num += 10;NSLog(@"arrValue == %@ num == %d",arrValue.toArray,num);dispatch_async(dispatch_get_main_queue(), ^{weakSelf.showLabel.text = dict[@"name"];});};//异常收集self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {weakSelf.jsContext.exception = exception;NSLog(@"exception == %@",exception);};// JS 操作对象KC_JSObject *kcObject = [[KC_JSObject alloc] init];self.jsContext[@"kcObject"] = kcObject;// 打开相册self.jsContext[@"getImage"] = ^() {weakSelf.imagePicker = [[UIImagePickerController alloc] init];weakSelf.imagePicker.delegate = weakSelf;weakSelf.imagePicker.allowsEditing = YES;weakSelf.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;[weakSelf presentViewController:weakSelf.imagePicker animated:YES completion:nil];};}#import <Foundation/Foundation.h> #import <JavaScriptCore/JavaScriptCore.h>@protocol KCProtocol <JSExport>- (void)letShowImage; JSExportAs(getSum, -(int)getSum:(int)num1 num2:(int)num2);@end@interface KC_JSObject : NSObject<KCProtocol> @end#import "KC_JSObject.h"@implementation KC_JSObject- (void)letShowImage{NSLog(@"打开相册,上传图片"); }- (int)getSum:(int)num1 num2:(int)num2{return num1+num2; }@end
四、WebViewJavascriptBridge
https://github.com/marcuswestin/WebViewJavascriptBridge
转载于:https://www.cnblogs.com/madeByGx/p/9896706.html
OC与JS交互 初体会相关推荐
- (0085)iOS开发之OC与JS交互高级用法(JavaScriptCore)
前述:JavaScriptCore你不知道的OC与JS之间交互.OC与JS之间用model实现交互.通讯.传值!好玩! 几乎三年来一直断断续续接触OC与JS交互,每次觉得UIWebView OC与JS ...
- iOS OC与JS交互(WebView监听事件)
在iOS应用的开发过程中,我们经常会使用到WebView,当我们对WebView进行操作的时候,有时会需要进行源生的操作.那么我记下来就与大家分享一下OC与JS交互. 首先先说第一种方法,并没有牵扯O ...
- 通过WebViewJavascriptBridge实现OC与JS交互
这里照搬Github的Demo,其实还是很易懂的,首先,要在控制器的.h文件当中实现浏览器控件的协议: 1 #import <UIKit/UIKit.h> 2 3 @interface E ...
- 对 WKWebView js交互的简单封装
文章目录 1.WKWebView使用流程 2.核心方法 3.封装流程 3.1.初始化 3.2.加载URL 3.3.OC与js交互 3.3.1.监听js消息 3.3.2.注入js消息 3.3.3.移除j ...
- [转]OC与JS的交互详解
事情的起因还是因为项目需求驱动.折腾了两天,由于之前没有UIWebView与JS交互的经历,并且觉得这次在功能上有一定的创造性,特此留下一点文字,方便日后回顾. 我要实现这样一个需求:按照本地的CSS ...
- iOS与JS交互的4种方法
iOS与JS交互的方法: 1.拦截url(适用于UIWebView和WKWebView) 2.JavaScriptCore(只适用于UIWebView,iOS7+) 3.WKScriptMessage ...
- OC和JS互相调用小框架
鄙人不才献上一份UIWebView和JS交互的桥接框架 不多说直接上货吧!!! 献上框架.m文件的内部实现和代码注释 导入<objc/runtime.h> #import "UI ...
- 关于UIWebView与js交互的问题
这个问题,在网上能看到不少,主要通过调用UIWebView的一个方法stringByEvaluatingJavaScriptFromString 来实现,与js的交互问题,我想可能用的过程中会出现不少 ...
- ios传值给js_深入剖析 iOS 与 JS 交互
前言 Web 页面中的 JS 与 iOS Native 如何交互是每个 iOS 猿必须掌握的技能.而说到 Native 与 JS 交互,就不得不提一嘴 Hybrid. Hybrid 的翻译结果并不是很 ...
最新文章
- ubuntu mysql 更新时间_Ubuntu Server 修改mysql timeout超时时间
- 真香 | 有了这个神器,学习 Vim 终于不难了!
- 【bzoj1212】[HNOI2004]L语言 AC自动机
- n皇后问题java版
- 数组转json去除首尾引号_诞生于JavaScript,json的前世今生
- 网页搜索怎么显示排名_深圳seo搜索排名优化效果怎么样
- C++虚函数表和多态
- 一个好用的PHP验证码类
- python基础布尔和None(三)
- 物联网卡产品的应用和拓展
- 【Leetcode】打家劫舍 I and 打家劫舍 II(动态规划)PYTHON
- JMeter设置集合点
- 快速注册认证小程序,三分钟学会免300元认证企业小程序
- 【短期投资理财 二】信用卡实战操作
- win10换开始菜单工具ClassicShell
- 干货!ERP在企业财务管理中的应用问题分析与解决办法
- 为企业出海“搭桥”,汇量科技靠什么出圈?
- 微信定位精灵服务器或网络异常,微信定位精灵系统界面无法更新怎么办
- 路由器的类型及衡量路由器性能的主要参数指标
- linux 发送at指令,AT指令(打电话与发短信)