iOS开发日常-原生与H5交互逻辑

背景

  随着H5功能愈发的强大,混合开发势在必行,其中涉及的原生与JS的交互逻辑如何设定就成了当务之急。

之前的方案

  1.通过URL截取方法名和参数方式(缺点:截取麻烦)

  2.运用JavaScriptCore框架,通过JSContenxt对象注入方法(缺点:页面重定向后需要重新注入)

  3.舍弃UIWebView,采用WKWebView,新容器提供js与原生互调方法userContentController:didReceiveScriptMessage:方法(缺点:见通病)

  这三种方案通病:当js调用native时,有时需要通过回调来获取相应的信息,然上述三种方法均不可实现。

现行方案

js端

/*************iOS原生与web交互相关事件***************/
var DQSBridgeEvent = {

	_listeners : {},

	addEvent : function(type, fn) {
		if (typeof this._listeners[type] === "undefined") {
			this._listeners[type] = [];
		}
		if (typeof fn === "function") {
			this._listeners[type].push(fn);
		}
		return this;
	},

	fireEvent : function(type, param) {
		var arrayEvent = this._listeners[type];
		if (arrayEvent instanceof Array) {
			for (var i = 0, length = arrayEvent.length; i < length; i += 1) {
				if (typeof arrayEvent[i] === "function") {
					arrayEvent[i](param);
				}
			}
		}
		return this;
	},

	removeEvent : function(type, fn) {
		var arrayEvent = this._listeners[type];
		if (typeof type === "string" && arrayEvent instanceof Array) {
			if (typeof fn === "function") {
				for (var i = 0, length = arrayEvent.length; i < length; i += 1) {
					if (arrayEvent[i] === fn) {
						this._listeners[type].splice(i, 1);
						break;
					}
				}
			} else {
				delete this._listeners[type];
			}
		}
		return this;
	}
};

var DQSEventHandler = {
	//方法调用
	callNativeFunction : function(nativeMethodName, params, callBackID, callBack) {
		
		var message;

		if (!callBack) {

			message = {
				'methodName' : nativeMethodName,
				'params' : params
			};
			window.webkit.messageHandlers.DQSEventHandler.postMessage(message);

		} else {
			message = {
				'methodName' : nativeMethodName,
				'params' : params,
				'callBackID' : callBackID
			};
			if (!DQSBridgeEvent._listeners[callBackID]) {
				DQSBridgeEvent.addEvent(callBackID, function(data) {

					callBack(data);

				});
			}
			window.webkit.messageHandlers.DQSEventHandler.postMessage(message);
		}

	},

	//执行js回调
	callBack : function(callBackID, data) {

		DQSBridgeEvent.fireEvent(callBackID, data);

	},

	//删除所有交互方法
	removeAllCallBacks : function(data) {
		
		DQSBridgeEvent._listeners = {};
	}

};

//测试调用(js调用native)
DQSEventHandler.callNativeFunction("judgeLogin", null, "judgeLoginCallBack", function(token){
		if (token == "" || token == null) {
			//未登录逻辑处理!
			alert("未登录");
		} else {
			//已登录逻辑处理!
			alert("已登录");
		}
	});

Objective-C端

//注册js与原生交互对象
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"DQSEventHandler"];

//js调用native
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.name isEqualToString:@"DQSEventHandler"]) {
        NSString *methodName = message.body[@"methodName"];
        NSDictionary *params = message.body[@"params"];
        NSString *callBackId = message.body[@"callBackID"];
        //根据方法名和回调ID来进行相应处理
        ...
        //测试
        if ([methodName isEqualToString:@"judgeLogin"]) {
        	[self judgeLogin:^(response) {
				NSString *js = [NSString stringWithFormat:@"DQSEventHandler.callBack('%@','%@');",callBackId,response];
    [self.webView evaluateJavaScript:js completionHandler:NULL];
			}];
        }
    }
}

//native调用js
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    NSString *js = @"";
    [webView evaluateJavaScript:js completionHandler:^(id response, NSError * _Nullable error) {

    }];
}

//注销js与原生交互事件
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"DQSEventHandler"];
[self.webView evaluateJavaScript:@"DQSEventHandler.removeAllCallBacks()" completionHandler:NULL];

//测试调用
- (void)judgeLogin:(void(^)(id response))callBack{
    NSString *token = @"";
    if(callBack){
        callBack(token);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值