1.OC与JS交互之UIWebView
创建一个UIWebView 并加载
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height-20)];
_webView.delegate = self;
_webView.scrollView.bounces = NO;
/ 添加 webiview
[self.view addSubview:self.webView];
// 加载请求
// 1.URL
NSURL *url = [NSURL URLWithString:HOME_URL];
// 2.创建请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3.加载请求
[self.webView loadRequest:request];
UIWebView delegate 协议方法
//网页即将开始加载
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
//网页开始加载
- (void)webViewDidStartLoad:(UIWebView *)webView;
//网页加载完成
- (void)webViewDidFinishLoad:(UIWebView *)webView;
//网页加载失败
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;
//UIWebView自带了一个方法, 可以直接调用JS代码(转化为string类型的js代码)
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
//例如修改id为‘html’标签内部的text属性
[web stringByEvaluatingJavaScriptFromString:@"document.getElementById('html').innerText='修改内容'"];
//也可以执行多行js代码
[web stringByEvaluatingJavaScriptFromString:@"var div = document.getElementById('html'); div.innerText = '修改内容'"];
// JS调用OC
一,js里面直接调用方法
方法1
代码如下
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(@"%@",request.URL );
if ([[request.URL absoluteString] hasPrefix:[NSString stringWithFormat:@"%@/stats/index?orgId=",PR_AppDotNetAPIBaseURLString]]) {
[self menuLeftBarButton];
} else {
[self setDefaultBackButton];
[self setRightButton];
}
return YES;
}
在这个网页即将加载的方法里面做一些网址的截取,可以做一些相应的处理,对某些特定的网址做不同的处理。至于返回YES 还是NO 就根据你们的需求做处理
方法2
在网页加载完成之后使用苹果推荐的JavaScriptCore
对于有参数传递的也是有两种方法获取,详细见图
代码如下
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
if ([[webView.request.URL absoluteString] hasPrefix:[NSString stringWithFormat:@"%@/stats/index?orgId=",PR_AppDotNetAPIBaseURLString]]) {
self.title = @"我的机构";
} else {
self.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}
if ([[webView.request.URL absoluteString] hasPrefix:[NSString stringWithFormat:@"%@/newstats/hot/",PR_AppDotNetAPIBaseURLString]]) {
[self touchToDetail];
}
[self invokeJS];
}
- (void)invokeJS {
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"orgBuyCoin"] = ^() {
BuyCoinViewController *vc = [[BuyCoinViewController alloc] initWithNibName:@"BuyCoinViewController" bundle:nil];
vc.whicePay = @"BCPay";
vc.productType = @"4";
vc.title = @"机构购买学币";
[self.navigationController pushViewController:vc animated:YES];
};
context[@"buyMembers"] = ^() {
NSNumber *MemberCount = [[NSNumber alloc] init];
NSArray *args = [JSContext currentArguments];
MemberCount = (NSNumber *)args[0];
JSValue *this = [JSContext currentThis];
NSLog(@"this8888888888888: %@",this);
NSLog(@"-------End Log-------");
BuyMembersViewController *vc = [[BuyMembersViewController alloc] initWithNibName:@"BuyMembersViewController" bundle:nil];
//返回的
NSLog(@"-----MemberCount:%@", MemberCount);
vc.MemberCount = MemberCount;
[self.navigationController pushViewController:vc animated:YES];
};
}
二,js里面通过对象调用方法 这里以微信和支付宝支付为例子
这里要借助 JSExport
可以制定一个协议
@protocol JSLivingDelegate <JSExport>
/**
* 支付宝支付
*
* @param ali_pay_data 支付数据
* @param ali_order 订单
*/
JSExportAs(ali_pay,
- (void)ali_sub:(id)ali_pay_data order:(id)ali_order
);
//微信支付
JSExportAs(wx_pay,
- (void)wxpay_sub:(NSString *)appId
nonceStr:(NSString *)nonceStr
outTradeNo:(NSString *)outTradeNo
package:(NSString *)package
partnerid:(NSString *)partnerid
paySign:(NSString *)paySign
prepayid:(NSString *)prepayid
signTyp:(NSString *)signTyp
timeStamp:(NSString *)timeStamp
);
@end
遵循协议实现对应的OC方法就行了
//OC调用JS
方法1
代码如下
iOS 7之前
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"addressCallBack('%@','%@','%@','%@');",provincecid,province,citycid,city]];
方法2
NSString * method = @"dolike";
JSValue * function = [self.context objectForKeyedSubscript:method];
//这里面的a,b,c就是OC调用JS的时候给JS传的参数
[function callWithArguments:@[a,b,c]];
2.OC与JS交互之WKWebView
创建一个WKWebView 并加载
self.webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 20, kScreenWidth, kScreenHeight-20) configuration:config];
self.webView.scrollView.bounces = NO;
self.webView.UIDelegate = self;
self.webView.navigationDelegate = self;
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
WKWebView中的三个代理方法
1 WKNavigationDelegate
// 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
页面跳转的代理方法有三种,分为(收到跳转与决定是否跳转两种)
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation: (WKNavigation *)navigation;
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
2 WKUIDelegate
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
/ 界面弹出警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler;
// 界面弹出确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
// 界面弹出输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;
3 WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController
didReceiveScriptMessage:(WKScriptMessage *)message;
//JS调用OC
也可以截取网址这里就不在累述
在创建web的时候 self.webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 20, kScreenWidth, kScreenHeight-20) configuration:config];
配置 config 对js 的方法进行类似注册的操作
WKWebViewConfiguration *config = [WKWebViewConfiguration new];
//初始化偏好设置属性:preferences
config.preferences = [WKPreferences new];
//The minimum font size in points default is 0;
config.preferences.minimumFontSize = 10;
//是否支持JavaScript
config.preferences.javaScriptEnabled = YES;
//不通过用户交互,是否可以打开窗口
config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
[config.userContentController addScriptMessageHandler:self name:@"AppModel"];
[config.userContentController addScriptMessageHandler:self name:@"ConfirmAccepts"];
[config.userContentController addScriptMessageHandler:self name:@"ChuanPhone"];
然后在代理做对应的处理和参数的接收
- (void)userContentController:(WKUserContentController *)userContentController
didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"%@",NSStringFromSelector(_cmd));
NSLog(@"%@",message.body);
if ([message.name isEqualToString:@"AppModel"]) {
[self showMsg:@"我收到js的AppModel"];
}
if ([message.name isEqualToString:@"ConfirmAccepts"]) {
NSString *info = [NSString stringWithFormat:@"你好 %@, 很高兴见到你",message.body];
[self showMsg:info];
}
if ([message.name isEqualToString:@"ChuanPhone"]) {
NSArray *array = message.body;
NSString *info = [NSString stringWithFormat:@"这是我的手机号: %@, %@ !!",array.firstObject,array.lastObject];
[self showMsg:info];
}
}
//OC 调用JS
//方法 setName
[webView evaluateJavaScript:@"setname('张三')" completionHandler:nil];
//此处 setname为JS定义的方法名, 内部 ‘张三’为传给JS的参数。 如果setname方法需要传入一个json或者array等非字符参数, 需要用format方法将其转为string类型,在调用evaluate方法。例如
NSString * para = [NSString stringWithFormat:@"setname('%@')",json];
希望能够帮助你,有什么问题欢迎留言。