javascript
swift 原生给h5发消息_Swift-WKWebView与JavaScript的细节,H5页面跳转原生界面
大家(也包括我)要學會 明白一件事情(注意斷句,哈哈)。優秀的程序猿會將問題簡單化。
世界上有10種人,一種是先把問題復雜化,然后在一點點的做減法;另一種是先把問題簡單化,然后在慢慢的做加法;(好了該進入正題了哈哈!) 文中有源碼地址
一,加載HTML的幾種方式
/**
* 1,加載網絡html
*/
NSString * surl = @"http://192.168.3.134:7080/toCompanyTouch";
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:surl]];
[self.wkwebView loadRequest:request];
/**
* 2,加載本地html 資源(內容)
*/
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交互沒有想象中那么不著邊際
二,UIWebView與JS交互
首先使用到 框架中的 JSContext,JSExport對象。
JSContext Native和JS交互時,連接兩者的上下文,
JSExport Native和JS交互協議。(實現方法調用時必須實現的協議)
然后通過KVC的方式獲得 JSContext(上線時可能有風險,還可以通過KVO的方式獲得)
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
JSContext * context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// self 是裝有 UIWebView的控制器,并且它遵守了 JSExport 協議
//把self這個對象放到上下文中,通過VC這個key可以找到self這個對象
[context setObject:self forKeyedSubscript:@"VC"];
}1
2
3
4
5
6
7
在然后就可以在JS頁面中使用這個VC了,VC能對應上OC中那個controller
不要忘記在UIViewController中遵守并實現JSExport
//遵守協議
@protocol JS_OCCOnnectProtocolInWeb
- (void)testLog:(NSDictionary*)dict;
@end
@interface UIWeb_VC ()
@property UIWebView * webView;
@end
@implementation UIWeb_VC
//實現協議方法
- (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中調用就方便了
UIWeb測試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的瀏覽器內核,在性能上高于UIWebView。
wk的交互需要用到 MessageHandler,在實例化WKWebView時配置一下WKUserContentController,并且遵守 WKScriptMessageHandler 協議實現他的方法
- (void)viewDidLoad {
[super viewDidLoad];
WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc]init];
config.userContentController =[[WKUserContentController alloc]init];
//意思是將名字為 ocWkModth 的方法注冊到js中
[config.userContentController addScriptMessageHandler:self name:@"ocWkModth"];
self.wkwebView = [[WKWebView alloc]initWithFrame:self.view.boundsconfiguration:config];
}1
2
3
4
5
6
7
8
WKScriptMessageHandler 協議的方法。在這里可以接收到js傳來的參數
- (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中調用如下方法可以將信息傳遞到OC的 WKScriptMessageHandler 協議方法中
測試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交互肯定是需要一個橋梁,在UIWebView中使用的是下面這個方法
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));
}
/*其實就是這個樣子的,后面是swift的閉包*/
webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234abcd';", completionHandler: nil);1
2
3
4
5
6
這兩個方法是有返回值的,返回值就是html5頁面中 element的value(可以片面的理解為UILable的text),雖然這個方法能執行JavaScript的代碼,但只局限為可操作的一些元素和方法,這里給大家解釋一下js一些簡單的方法
/*通過這個id可以得到某個元素或者標簽*/
var lable_btn = document.getElementById('某個元素或者標簽的id');
/*可以set和get元素或者標簽的value*/
lable_btn.value = 'value的值';
/*通過這個ClassName可以得到某個元素或者標簽 的數組*/
var nodesInput = document.getElementsByClassName('input');
nodesInput[0].value = 'test';1
2
3
4
5
6
7
在h5頁面加載完成后,執行以下操作
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234';", completionHandler: nil);
/*其實就是這個樣子的,后面是swift的閉包*/
webView.evaluateJavaScript("document.getElementById('index-kw').value = '1234abcd';") { (any, err) -> Void in
/*any 其實就是返回值*/
NSLog("any=" + (any as! String));
}
}1
2
3
4
5
6
7
8
9
10
11
*效果如下,其中 index-kw 是百度收索框的元素 id,給這個id的value,賦值。出現如下效果
這就是一個簡單的交互*
但在實際開發中可能需要一些更高級的交互,這里沒有使用網上的一些框架
/*這里可以監聽和攔截 h5 頁面的 alert*/
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) ->Void) {
if message == "商量好的信息" {
/*這里可以談一個native的彈窗*/
//UIAlertController ....
}
}1
2
3
4
5
6
7
五,其他的交互機制–攔截機制
======H5頁面跳轉原生界面======
1,項目配置
在 info 里面 添加 URL Schemes
我在里添加的是 com.sir.pppig
然后在 appDegelate.m 中,監聽
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options
{
NSLog(@"----]");
if (!url) { return NO; }
// 可以在這里處理打開APP后的 業務邏輯
NSLog(@"new url= [%@]", url);
return YES;
}1
2
3
4
5
6
7
8
2,第一種 事件觸發
然后在瀏覽器中輸入 com.sir.pppig://, 就可以打開APP了,
點擊 open ,打開APP,
3,第二種事件觸發
在h5頁面觸發,
測試頁面
打開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); */
}
總結
以上是生活随笔為你收集整理的swift 原生给h5发消息_Swift-WKWebView与JavaScript的细节,H5页面跳转原生界面的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python读取有空行的csv_如何在使
- 下一篇: java清除输出内容_java – 从