iOS webView的高级用法之JS交互
2017-03-17 13:32
691 查看
前言:说起JS交互,很多童鞋会黯然色变,感觉很高深的样子。大部分小伙伴只知道一种,哪一种我也说说吧。
1.在webView中将要请求的时候,拦截URL,进行重定向,然而该场景实用有限,网上资料也很多下面说说另一种交互方式。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
2.先说一下这种交互方式应用的场景吧。
2.1:需求:假如贵公司在做一个金融项目,有一个版本功能需要提交个人资料信息,只是为了一个业务需要,那么通过h5做一套,然后iOS和Android只需要webView加载就行,明显提高了开发效率。。。如果贵公司的其他产品也想接入这个功能,那也能通过webview方式直接用了,所谓是牛逼哄哄,通用性特别强。
但是:(1):比如,webview里有一个上传身份证照片的功能,点击网页,需要iOS端调起相册功能。。如何交互??
(2): 加载的网页中,点击一个按钮,要查看订单详情功能,但是需要传会订单号,怎么办:
(3): 点击下一步,,iOS端进入下一个界面;??
这就牵扯到JS调用OC方法,传递参数等等。
3.本文将非常详细的说明使用方法,一句代码不少的说明,你只需要按照步骤操作,一定能运行出你想要的JS交互场景,包你能派上大用场。。废话不说了,开始吧
正文:JS交互,就是js 中通过一个对象来调用方法的
1.js交互,首先我们要准备一个html文件,没有网页文件,要不然怎么交互:至于这些东西怎么创建,这里不做介绍,楼主最后会附上联系方式,提供demo,demo中有,直接复制就行。
1.1.首先准备一个html文件,html文件里引用了外部的JS文件
2.js文件,里面实现了html文件里的一些按钮的点击事件
图片里非常清楚的注释了一些重要代码的注释,非常详细,搞得自己很会h5一样,程序员,不能放弃任何一次装b的机会,
⚠️注意: 这里在网页中写了4个按钮,,分别调OC的方法
1. 点击按钮,唤起系统相册功能;
2. 就是简单的调一个方法
3. 调用一个参数的方法
4. 调用多个参数的方法,这里举例是两个。
2.首先创建一个类 继承NSObject ,并且规定一个协议,直接上代码
2.1>创建TestJSObject.h头文件
#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
2.2:然后在.m中实现声明的方法,这4个方法,都会被调用
#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
3最后在控制器中
3.1>在懒加载中,设置了web view的url,是一个本地文件,也就是我们一开始写的html文件的路径。
#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
[b]4.上一些运行图吧[/b]
4.1:web view的界面图;;
4.2,点击第一个按钮,通过调
ZTHShowPicker方法,内部block的调用,唤起控制器中actionsheet。
4.3,点击最后两个按钮,,第一个传递订单号,第二个传递订单号和姓名,点了两次,打印了两次
[b]5.关于带多个参数的JS回调,OC中对应方法的写法:
[/b]
比如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 *)orderNumber[b]ndParametertwo:([/b]NSString *)name;
JSExport协议的类,又定义了一个协议,声明实现的方法和js中按钮的点击事件方法名称一致,用来一一映射。。最后在控制器中webview加载完毕之后,
TestJSObject *testJO=[TestJSObjectnew];
testJO.showPickerBlock = ^{
[selfshowImagePicker];
};
_context[@"testobject"]=testJO;
当然OC内部肯定封装了很多东西匹配他们,,这不用我们管,,最后我们看看JS文件中的一个方法名
testobject.ZTHpay();
原来是根据testobject这个对象联系起来的,
楼主语言能力不行,不知道有没有绕晕你,但是你只要把demo跑一跑,问题就都能解决了。。当然你要是知道点h5的东西,那肯定更简单咯
就先写到这,回头再完善,楼主其他文章里有联系方式,比如这两篇文章就有联系方式,如有不对的地方,欢迎指正。。想要demo的童鞋,可以加扣扣。。在下面的文章最后有。先好好上会班。
http://blog.csdn.net/horisea/article/details/51872619
http://blog.csdn.net/horisea/article/details/52025886
当然楼主也不是凭空就会的,本文参考链接,当时他说的是技术点,我把细节说的很细,结合下更好哦。 http://blog.csdn.net/lwjok2007/article/details/47058795
1.在webView中将要请求的时候,拦截URL,进行重定向,然而该场景实用有限,网上资料也很多下面说说另一种交互方式。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
2.先说一下这种交互方式应用的场景吧。
2.1:需求:假如贵公司在做一个金融项目,有一个版本功能需要提交个人资料信息,只是为了一个业务需要,那么通过h5做一套,然后iOS和Android只需要webView加载就行,明显提高了开发效率。。。如果贵公司的其他产品也想接入这个功能,那也能通过webview方式直接用了,所谓是牛逼哄哄,通用性特别强。
但是:(1):比如,webview里有一个上传身份证照片的功能,点击网页,需要iOS端调起相册功能。。如何交互??
(2): 加载的网页中,点击一个按钮,要查看订单详情功能,但是需要传会订单号,怎么办:
(3): 点击下一步,,iOS端进入下一个界面;??
这就牵扯到JS调用OC方法,传递参数等等。
3.本文将非常详细的说明使用方法,一句代码不少的说明,你只需要按照步骤操作,一定能运行出你想要的JS交互场景,包你能派上大用场。。废话不说了,开始吧
正文:JS交互,就是js 中通过一个对象来调用方法的
1.js交互,首先我们要准备一个html文件,没有网页文件,要不然怎么交互:至于这些东西怎么创建,这里不做介绍,楼主最后会附上联系方式,提供demo,demo中有,直接复制就行。
1.1.首先准备一个html文件,html文件里引用了外部的JS文件
2.js文件,里面实现了html文件里的一些按钮的点击事件
图片里非常清楚的注释了一些重要代码的注释,非常详细,搞得自己很会h5一样,程序员,不能放弃任何一次装b的机会,
⚠️注意: 这里在网页中写了4个按钮,,分别调OC的方法
1. 点击按钮,唤起系统相册功能;
2. 就是简单的调一个方法
3. 调用一个参数的方法
4. 调用多个参数的方法,这里举例是两个。
2.首先创建一个类 继承NSObject ,并且规定一个协议,直接上代码
2.1>创建TestJSObject.h头文件
#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
2.2:然后在.m中实现声明的方法,这4个方法,都会被调用
#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
3最后在控制器中
3.1>在懒加载中,设置了web view的url,是一个本地文件,也就是我们一开始写的html文件的路径。
#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
[b]4.上一些运行图吧[/b]
4.1:web view的界面图;;
4.2,点击第一个按钮,通过调
ZTHShowPicker方法,内部block的调用,唤起控制器中actionsheet。
4.3,点击最后两个按钮,,第一个传递订单号,第二个传递订单号和姓名,点了两次,打印了两次
[b]5.关于带多个参数的JS回调,OC中对应方法的写法:
[/b]
比如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 *)orderNumber[b]ndParametertwo:([/b]NSString *)name;
最后说两句:这可能是JS交互中最好用的方法了,总结一下也就是我们在OC中定义一个遵守
JSExport协议的类,又定义了一个协议,声明实现的方法和js中按钮的点击事件方法名称一致,用来一一映射。。最后在控制器中webview加载完毕之后,TestJSObject *testJO=[TestJSObjectnew];
testJO.showPickerBlock = ^{
[selfshowImagePicker];
};
_context[@"testobject"]=testJO;
当然OC内部肯定封装了很多东西匹配他们,,这不用我们管,,最后我们看看JS文件中的一个方法名
testobject.ZTHpay();
原来是根据testobject这个对象联系起来的,
楼主语言能力不行,不知道有没有绕晕你,但是你只要把demo跑一跑,问题就都能解决了。。当然你要是知道点h5的东西,那肯定更简单咯
就先写到这,回头再完善,楼主其他文章里有联系方式,比如这两篇文章就有联系方式,如有不对的地方,欢迎指正。。想要demo的童鞋,可以加扣扣。。在下面的文章最后有。先好好上会班。
http://blog.csdn.net/horisea/article/details/51872619
http://blog.csdn.net/horisea/article/details/52025886
当然楼主也不是凭空就会的,本文参考链接,当时他说的是技术点,我把细节说的很细,结合下更好哦。 http://blog.csdn.net/lwjok2007/article/details/47058795
相关文章推荐
- iOS webView的高级用法之JS交互,js与oc的相互调用(JavaScriptCore)
- iOS 基于JavaScriptCore 不等webView加载完毕就交互,网页获取原生内容。 webView的高级用法之JS交互,js与oc的相互调用
- ios中webview的高级用法(二) - webview与js的通信框架
- iOS中原生APP与JS交互 之 WebViewJavascriptBridge 的简单用法
- WebView(原生)与Js 交互 基本与高级用法
- ios中webview与js交互代码
- ios与js交互,获取webview完整url,title,获取元素并赋值跳转
- WebView的基本用法以及和js交互
- ios与js交互获取webview元素和赋值
- IOS Webview JS交互之事件拦截获取
- iOS webview 和 js 交互
- iOS ios与js交互,获取webview完整url,title,获取元素并赋值跳转
- ios 点击webview获取图片url (js交互)
- ios中webview的高级用法
- iOS开发使用WebViewJavascriptBridge实现OC与JS交互
- ios webview与JS的交互
- iOS开发日记27-WebView与JS的交互
- WebView用法与JS交互
- iOS解析---WebView和js交互原理
- iOS解析---WebView和js交互原理