javascript
swift 原生给h5发消息_Swift-WKWebView与JavaScript的细节,H5页面跳转原生界面
大家(也包括我)要學(xué)會(huì) 明白一件事情(注意斷句,哈哈)。優(yōu)秀的程序猿會(huì)將問(wèn)題簡(jiǎn)單化。
世界上有10種人,一種是先把問(wèn)題復(fù)雜化,然后在一點(diǎn)點(diǎn)的做減法;另一種是先把問(wèn)題簡(jiǎn)單化,然后在慢慢的做加法;(好了該進(jìn)入正題了哈哈!) 文中有源碼地址
一,加載HTML的幾種方式
/**
* 1,加載網(wǎng)絡(luò)html
*/
NSString * surl = @"http://192.168.3.134:7080/toCompanyTouch";
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:surl]];
[self.wkwebView loadRequest:request];
/**
* 2,加載本地html 資源(內(nèi)容)
*/
NSURL * url =[[NSBundle mainBundle] URLForResource:@"testH5" withExtension:@"html"];
NSString *path = [[NSBundle mainBundle] pathForResource:@"testH5" ofType:@"html"];
NSString * htmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[self.wkwebView loadHTMLString:htmlString baseURL:url];
/**
* 3,加載本地html url
*/
NSURL * url2 =[[NSBundle mainBundle] URLForResource:@"testH5" withExtension:@"html"];
[self.wkwebView loadFileURL:url2 allowingReadAccessToURL:url2];1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Native和js交互沒(méi)有想象中那么不著邊際
二,UIWebView與JS交互
首先使用到 框架中的 JSContext,JSExport對(duì)象。
JSContext Native和JS交互時(shí),連接兩者的上下文,
JSExport Native和JS交互協(xié)議。(實(shí)現(xiàn)方法調(diào)用時(shí)必須實(shí)現(xiàn)的協(xié)議)
然后通過(guò)KVC的方式獲得 JSContext(上線(xiàn)時(shí)可能有風(fēng)險(xiǎn),還可以通過(guò)KVO的方式獲得)
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
JSContext * context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// self 是裝有 UIWebView的控制器,并且它遵守了 JSExport 協(xié)議
//把self這個(gè)對(duì)象放到上下文中,通過(guò)VC這個(gè)key可以找到self這個(gè)對(duì)象
[context setObject:self forKeyedSubscript:@"VC"];
}1
2
3
4
5
6
7
在然后就可以在JS頁(yè)面中使用這個(gè)VC了,VC能對(duì)應(yīng)上OC中那個(gè)controller
不要忘記在UIViewController中遵守并實(shí)現(xiàn)JSExport
//遵守協(xié)議
@protocol JS_OCCOnnectProtocolInWeb
- (void)testLog:(NSDictionary*)dict;
@end
@interface UIWeb_VC ()
@property UIWebView * webView;
@end
@implementation UIWeb_VC
//實(shí)現(xiàn)協(xié)議方法
- (void)testLog:(NSDictionary*)dict
{
NSLog(@"---testLog--");
NSLog(@"dict=[%@]",dict);
}
@end1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
最后在js中調(diào)用就方便了
UIWeb測(cè)試1
打印信息如下
2017-12-06 15:18:58.645195+0800 TestHybriod[2378:1026324] ---testLog--
2017-12-06 15:18:58.646071+0800 TestHybriod[2378:1026324] dict=[{
page = testVC;
}]1
2
3
4
三,WKWebView與JS交互
1,WebKit中 WKWebView使用的是Safari的瀏覽器內(nèi)核,在性能上高于UIWebView。
wk的交互需要用到 MessageHandler,在實(shí)例化WKWebView時(shí)配置一下WKUserContentController,并且遵守 WKScriptMessageHandler 協(xié)議實(shí)現(xiàn)他的方法
- (void)viewDidLoad {
[super viewDidLoad];
WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc]init];
config.userContentController =[[WKUserContentController alloc]init];
//意思是將名字為 ocWkModth 的方法注冊(cè)到j(luò)s中
[config.userContentController addScriptMessageHandler:self name:@"ocWkModth"];
self.wkwebView = [[WKWebView alloc]initWithFrame:self.view.boundsconfiguration:config];
}1
2
3
4
5
6
7
8
WKScriptMessageHandler 協(xié)議的方法。在這里可以接收到j(luò)s傳來(lái)的參數(shù)
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
NSLog(@"body=[%@]",message.body);
NSLog(@"name=[%@]",message.name);
NSLog(@"frameInfo.absoluteString=[%@]",message.frameInfo.request.URL.absoluteString);
}1
2
3
4
5
6
7
在JS中調(diào)用如下方法可以將信息傳遞到OC的 WKScriptMessageHandler 協(xié)議方法中
測(cè)試1
打印信息如下
2017-12-06 14:24:47.955640+0800 TestHybriod[2047:784478] body=[{
page = testVC;
result = success;
}]
2017-12-06 14:24:47.955845+0800 TestHybriod[2047:784478] name=[ocWkModth]1
2
3
4
5
四,其他粗暴的方法
在Native和js交互肯定是需要一個(gè)橋梁,在UIWebView中使用的是下面這個(gè)方法
webView.stringByEvaluatingJavaScript(from: "document.getElementById('index-kw').value = '1234';");1
在WKWebView中使用的是
webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234abcd';") { (any, err) -> Void in
NSLog("any=" + (any as! String));
}
/*其實(shí)就是這個(gè)樣子的,后面是swift的閉包*/
webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234abcd';", completionHandler: nil);1
2
3
4
5
6
這兩個(gè)方法是有返回值的,返回值就是html5頁(yè)面中 element的value(可以片面的理解為UILable的text),雖然這個(gè)方法能執(zhí)行JavaScript的代碼,但只局限為可操作的一些元素和方法,這里給大家解釋一下js一些簡(jiǎn)單的方法
/*通過(guò)這個(gè)id可以得到某個(gè)元素或者標(biāo)簽*/
var lable_btn = document.getElementById('某個(gè)元素或者標(biāo)簽的id');
/*可以set和get元素或者標(biāo)簽的value*/
lable_btn.value = 'value的值';
/*通過(guò)這個(gè)ClassName可以得到某個(gè)元素或者標(biāo)簽 的數(shù)組*/
var nodesInput = document.getElementsByClassName('input');
nodesInput[0].value = 'test';1
2
3
4
5
6
7
在h5頁(yè)面加載完成后,執(zhí)行以下操作
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234';", completionHandler: nil);
/*其實(shí)就是這個(gè)樣子的,后面是swift的閉包*/
webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234abcd';") { (any, err) -> Void in
/*any 其實(shí)就是返回值*/
NSLog("any=" + (any as! String));
}
}1
2
3
4
5
6
7
8
9
10
11
*效果如下,其中 index-kw 是百度收索框的元素 id,給這個(gè)id的value,賦值。出現(xiàn)如下效果
這就是一個(gè)簡(jiǎn)單的交互*
但在實(shí)際開(kāi)發(fā)中可能需要一些更高級(jí)的交互,這里沒(méi)有使用網(wǎng)上的一些框架
/*這里可以監(jiān)聽(tīng)和攔截 h5 頁(yè)面的 alert*/
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) ->Void) {
if message == "商量好的信息" {
/*這里可以談一個(gè)native的彈窗*/
//UIAlertController ....
}
}1
2
3
4
5
6
7
五,其他的交互機(jī)制–攔截機(jī)制
======H5頁(yè)面跳轉(zhuǎn)原生界面======
1,項(xiàng)目配置
在 info 里面 添加 URL Schemes
我在里添加的是 com.sir.pppig
然后在 appDegelate.m 中,監(jiān)聽(tīng)
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options
{
NSLog(@"----]");
if (!url) { return NO; }
// 可以在這里處理打開(kāi)APP后的 業(yè)務(wù)邏輯
NSLog(@"new url= [%@]", url);
return YES;
}1
2
3
4
5
6
7
8
2,第一種 事件觸發(fā)
然后在瀏覽器中輸入 com.sir.pppig://, 就可以打開(kāi)APP了,
點(diǎn)擊 open ,打開(kāi)APP,
3,第二種事件觸發(fā)
在h5頁(yè)面觸發(fā),
測(cè)試頁(yè)面
打開(kāi)APP
document.getElementById('openApp').onclick = function (e) {
/* location.href = 'com.sir.pppig://';
setTimeout(function() {
location.href = '/toAppMobilePageTouch';
}, 250);
setTimeout(function() {
location.reload();
}, 1000); */
/* var ifr = document.createElement('iframe');
ifr.src = 'com.sir.pppig://';
ifr.style.display = 'none';
document.body.appendChild(ifr);
setTimeout(function(){
document.body.removeChild(ifr);
}, 3000); */
}
總結(jié)
以上是生活随笔為你收集整理的swift 原生给h5发消息_Swift-WKWebView与JavaScript的细节,H5页面跳转原生界面的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python读取有空行的csv_如何在使
- 下一篇: java清除输出内容_java – 从