做客户端开发,肯定避免不了JS交互,于是自己对苹果接口做了个简易封装:
JSExport-->UIWebView+Interaction、WKScriptMessageHandler -->WKWebView+Interaction以备以后使用。
代码非常简洁,见这里:https://github.com/V5zhou/JSInteraction.git
旧方式
旧的交互方式有通过UIWebViewDelegate实现的:JS与客户端定义好跳转页面参数,在将要跳转时捕获关键字,然后处理业务。
iOS端:
1
2
3
4
5
6
7
8
9
|
- ( BOOL )webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *urlString = [[request URL] absoluteString];
if ([urlString isEqualToString:@ "objc://loading" ]) {
if (_gotoRootViewController) {
_gotoRootViewController();
}
}
return YES;
}
|
JS端:
1
2
3
4
5
6
7
8
|
<!DOCTYPE html>
< html >
< title >test</ title >
< meta charset = "utf-8" >
< body >
< a href = "javascript:document.location = 'objc://loading'" rel = "external nofollow" class = "btn" >这是交互按钮</ a >
</ body >
</ html >
|
UIWebView+JSExport方式
导入JavaScriptCore.framework,并导入我的扩展类#import "UIWebView+Interaction.h"。
使用方式
OC调JS:
1
|
[_webView InterActionToJs:@ "alertMobile('15625298071')" ];
|
JS调OC:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[self.webView InterActionToOc:^(InterActionOcType functionType, NSDictionary *param) {
switch (functionType) {
case InterActionOcType_alert:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:param[@ "title" ] message:param[@ "content" ] delegate:nil cancelButtonTitle:nil otherButtonTitles:@ "确定" , nil];
[alert show];
}
break ;
case InterActionOcType_present:
{
self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
Class Cls = NSClassFromString(param[@ "toController" ]);
BOOL isAnimate = [param[@ "animate" ] boolValue];
UIViewController *ctl = [[Cls alloc] init];
[self presentViewController:ctl animated:isAnimate completion:nil];
}
break ;
default :
break ;
}
}];
}
|
添加动作
1
2
3
4
5
6
|
//自定义添加功能类型
typedef NS_ENUM(NSUInteger, InterActionOcType) {
InterActionOcType_alert = 0,
InterActionOcType_present,
InterActionOcType_xxxxxxx, //有啥需求就和这里添加
};
|
并且对应的html中添加JS,参数封装为字典形式。例:
1
2
3
4
5
6
|
function myPresent(ctl) {
var param = new Array();
param[ "animate" ] = 1;
param[ "toController" ] = "SecondViewController" ;
WebViewInteraction.callBack(1, param);
}
|
其中callBack是通过这个JSExport实现的
1
2
3
4
5
6
|
@protocol WebViewJSExport <JSExport>
JSExportAs
(callBack /** callBack 作为js方法的别名 */ ,
- ( void )awakeOC:(InterActionOcType)type param:(NSDictionary *)param
);
@end
|
WKWebView+WKScriptMessageHandler方式
导入WebKit.framework,并导入我的扩展类#import "WKWebView+Interaction.h"。
使用方式
OC调JS:
1
|
[self.wkWebView InterActionToJs:@ "JSReloadTitle('你点了刷新JS按钮,我没猜错!')" ];
|
JS调OC:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
//注册交互类型
[self.wkWebView registerScriptTypes:@{@ "OCDismiss" : @(WKInterActionOcType_dismiss),
@ "OCShowAlert" : @(WKInterActionOcType_alert)}];
[self.wkWebView InterActionToOc:^(WKInterActionOcType functionType, NSDictionary *param) {
switch (functionType) {
case WKInterActionOcType_dismiss:
{
BOOL isAnimate = [param[@ "animate" ] boolValue];
[self dismissViewControllerAnimated:isAnimate completion:nil];
}
break ;
case WKInterActionOcType_alert:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@ "JS去做平方" message:nil delegate:self cancelButtonTitle:@ "取消" otherButtonTitles:@ "确定" , nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
break ;
default :
break ;
}
}];
|
添加动作
1
2
3
4
5
6
|
//自定义添加功能类型
typedef NS_ENUM(NSUInteger, WKInterActionOcType) {
WKInterActionOcType_alert = 0,
WKInterActionOcType_dismiss,
WKInterActionOcType_xxxxxxx, //有啥需求就和这里添加
};
|
并且对应的html中添加JS,参数封装为字典形式。例:
1
2
3
4
|
//js调oc
function myDismiss() {
window.webkit.messageHandlers.OCDismiss.postMessage({ "animate" : 1}); //这里的OCDismiss对应注册类型
}
|
其中callBack是通过WKScriptMessageHandler实现的
1
2
3
4
5
6
7
8
9
10
|
- ( void )userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
dispatch_async(dispatch_get_main_queue(), ^{
NSString *name = message.name;
NSDictionary *value = message.body;
WKInterActionOcType type = [self.typeDict[name] integerValue];
if (self.block) {
self.block(type, value);
}
});
}
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.jianshu.com/p/5b2bbd283e2f?utm_source=tuicool&utm_medium=referral