iOS webView的高级用法之JS交互
来源:互联网 发布:新型网络创业 编辑:程序博客网 时间:2024/04/30 02:49
前言:说起JS交互,很多童鞋会黯然色变,感觉很高深的样子。大部分小伙伴只知道一种,哪一种我也说说吧。
1.在webView中将要请求的时候,拦截URL,进行重定向,然而该场景实用有限,网上资料也很多下面说说另一种交互方式。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
@protocol TestJSObjectProtocol <JSExport>
/// 调支付
- (void)ZTHpay;
/// 调系统相册
- (void)ZTHShowPicker;
/// 传参数回来 比如是一个订单号
- (void)ZTHPassParameter:(NSString *)orderNumber;
/// 传两个参数回来 比如是订单号,姓名
- (void)ZTHTestParameteroneAnd:(NSString *)orderNumber Parametertwo:(NSString *)name;
@end
@interface TestJSObject : NSObject<TestJSObjectProtocol>
///定义三种block,回调到控制器中;
@property (nonatomic,copy)void(^showPickerBlock)();
@end
#import "TestJSObject.h"
@implementation TestJSObject
- (void)ZTHpay{
NSLog(@"调了支付了-----------------");
}
- (void)ZTHShowPicker{
NSLog(@"调了相机-------------------");
dispatch_async(dispatch_get_main_queue(), ^{
//当然回调后要处理的逻辑,肯定不能在这个类里处理,这里采用block回调到控制器中处理,其余的三种方式都可以用这种方式处理,这里就不一一列举了
self.showPickerBlock();
});
}
- (void)ZTHPassParameter:(NSString *)orderNumber{
NSLog(@"%@", orderNumber);
}
//- (void)ZTHTestParameterone:(NSString *)orderNumber AndParametertwo:(NSString *)name{
// NSLog(@"订单号--%@姓名---%@", orderNumber, name);
//}
- (void)ZTHTestParameteroneAnd:(NSString *)orderNumber Parametertwo:(NSString *)name{
NSLog(@"订单号--%@姓名---%@", orderNumber, name);
}
@end
#pragma mark - lazy
- (UIWebView *)webview{
if (!_webview) {
_webview=[[UIWebViewalloc]initWithFrame:CGRectMake(0,200,self.view.bounds.size.width,300)];
_webview.delegate =self;
_webview.backgroundColor=[UIColorlightGrayColor];
NSString *htmlPath = [[NSBundlemainBundle]pathForResource:@"index"ofType:@"html"];
NSURL *localUrl = [[NSURLalloc]initFileURLWithPath:htmlPath];
[_webview loadRequest:[NSURLRequestrequestWithURL:localUrl]];
}
return _webview;
}
3.2.#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView{
//首先创建JSContext对象(此处通过当前webView的键获取到jscontext)
_context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//第二种情况,js是通过对象调用的,我们假设js里面有一个对象 testobject 在调用方法
//首先创建我们新建类的对象,将他赋值给js的对象
TestJSObject *testJO=[TestJSObjectnew];
testJO.showPickerBlock = ^{
[selfshowImagePicker];
};
_context[@"testobject"]=testJO;
}
到这里,就已经大功告成了。。。文中打红色的文字部分需要您仔细欣赏欣赏,,首先在TestJSObject.h中,我们声明了一个block属性,原因JS调用的方法实现在改类中,但是我们不能在这个类里处理逻辑,那当然需要一个属性回调到控制器中咯,于是在实现中调用了block,然后在上面写了block的实体,去调用
showImagePicker方法,然后你就可以处理了,,,,其实就是block最简单的用法,,但是,,肯定有很多童鞋不了解。。哈哈,不耽误。。下面附上控制器的所有代码,// Copyright © 2016年朱同海. All rights reserved.
// 本文主要介绍JS调用OC交互的方式
#import "ViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>
#import "TestJSObject.h"
@interface ViewController () <UIWebViewDelegate,UIActionSheetDelegate>
{
JSContext *_context;
}
@property (nonatomic,strong)UIWebView *webview;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColorcyanColor];
[self.viewaddSubview:self.webview];
}
#pragma mark - lazy
- (UIWebView *)webview{
if (!_webview) {
_webview=[[UIWebViewalloc]initWithFrame:CGRectMake(0,200,self.view.bounds.size.width,300)];
_webview.delegate =self;
_webview.backgroundColor=[UIColorlightGrayColor];
NSString *htmlPath = [[NSBundlemainBundle]pathForResource:@"index"ofType:@"html"];
NSURL *localUrl = [[NSURLalloc]initFileURLWithPath:htmlPath];
[_webview loadRequest:[NSURLRequestrequestWithURL:localUrl]];
}
return _webview;
}
#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView{
//首先创建JSContext对象(此处通过当前webView的键获取到jscontext)
_context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//第二种情况,js是通过对象调用的,我们假设js里面有一个对象 testobject 在调用方法
//首先创建我们新建类的对象,将他赋值给js的对象
TestJSObject *testJO=[TestJSObjectnew];
testJO.showPickerBlock = ^{
[self showImagePicker];
};
_context[@"testobject"]=testJO;
}
- (void)showImagePicker{
NSLog(@"开始唤起相机");
UIActionSheet *actionSheet = [[UIActionSheetalloc]
initWithTitle:@"请选择文件来源"
delegate:self
cancelButtonTitle:@"取消"
destructiveButtonTitle:nil
otherButtonTitles:@"拍照",@"从手机相册选择",nil];
[actionSheet showInView:self.view];
}
@end
ZTHShowPicker方法,内部block的调用,唤起控制器中actionsheet。
4.3,点击最后两个按钮,,第一个传递订单号,第二个传递订单号和姓名,点了两次,打印了两次
5.关于带多个参数的JS回调,OC中对应方法的写法:
比如JS中定义了这个方法
testobject.ZTHTestParameteroneAndParametertwo("1123425255","ZTH");那ZTHTestParameteroneAndParametertwo为方法名
那么OC中方法名可以这么写:1和2都是可行的
1.- (void)ZTHTestParameterone:(NSString *)orderNumber AndParametertwo:(NSString *)name;
2.- (void)ZTHTestParameteroneAnd:(NSString *)orderNumber Parametertwo:(NSString *)name;
聪明的你看出来了,只要是OC的方法名去掉:(冒号)拼接起来后,,和JS的方法名一致,那么都是会调用改方法的
千万不能作死:说,我这么拼也是我上面说的原理,那么很遗憾的告诉你,不可以,你把And拆开了,是一个单词,不识别(个人见解)
3.- (void)ZTHTestParameteroneA:(NSString *)orderNumberndParametertwo:(NSString *)name;最后说两句:这可能是JS交互中最好用的方法了,总结一下也就是我们在OC中定义一个遵守
JSExport协议的类,又定义了一个协议,声明实现的方法和js中按钮的点击事件方法名称一致,用来一一映射。。最后在控制器中webview加载完毕之后,
TestJSObject *testJO=[TestJSObjectnew];
testJO.showPickerBlock = ^{
[selfshowImagePicker];
};
_context[@"testobject"]=testJO;
当然OC内部肯定封装了很多东西匹配他们,,这不用我们管,,最后我们看看JS文件中的一个方法名testobject.ZTHpay();
原来是根据testobject这个对象联系起来的,- iOS webView的高级用法之JS交互
- iOS webView的高级用法之JS交互,js与oc的相互调用(JavaScriptCore)
- iOS 基于JavaScriptCore 不等webView加载完毕就交互,网页获取原生内容。 webView的高级用法之JS交互,js与oc的相互调用
- WebView(原生)与Js 交互 基本与高级用法
- iOS 之webView与js交互
- iOS WebView JS 交互
- ios webview与JS的交互
- iOS开发-WebView与JS的交互
- iOS中WebView和JS的交互
- iOS中webview和js的交互
- ios webView与js的交互
- iOS Webview与js的交互
- iOS webView与本地js的交互
- iOS高级编程之WebView & JavaScript交互详解
- ios中webview的高级用法
- ios中webview的高级用法
- 安卓高级 WebView的使用到 js交互
- WebView用法与JS交互
- thrift 框架学习笔记-之后再整理成文
- js 时间转化
- Swift 改变UILabel字体样式方法
- SharpGL
- IP地址分类与子网掩码有关计算
- iOS webView的高级用法之JS交互
- Spring 多线程
- 一台电脑开启多个Redis服务
- Android应用更新-自动检测版本及自动升级
- Leaf Camera Privacy Policy
- 对于Java程序猿学习的建议
- Eclipse 选择单行热键
- MacOS无法登录App Store修复
- 关于xml文件中的一些常用标签的意义