- 首先准备一份html的文件,并且导入到工程中,内容如下:
<html>
<head>
<meta charset="utf-8" />
<style>
body {
background-color: #d0e4fe;
}
h4 {
color: orange;
text-align: left;
font-family: "Thimes New Roman";
font-size: 20px;
}
</style>
</head>
<body>
<input type="text" />
<h4> 用户名 </h4>
<input type="text" />
<h4> 密码 </h4>
<button onclick="loginButtonClick()" style="font-size: 20px; color: red;"> 登录 </button>
<button onclick="logoutButtonClick()" style="font-size: 20px; color: red;"> 登出 </button>
<button onclick="testJsAlert()" style="font-size: 20px; color: red;"> 测试js弹出框 </button>
<script src="test2.js"> </script> // 这里有外部链接的js文件,为了结构上的清晰整洁
</body>
</html>
- 准备一份js文件,内容如下
function loginButtonClick() {
try {
webkit.messageHandlers.Login.postMessage("登录");
} catch(err) {
console.log('The native context does not exist yet');
}
}
function logoutButtonClick() {
try {
webkit.messageHandlers.Logout.postMessage("登出");
} catch(err) {
console.log('The native context does not exist yet');
}
}
function hello(firstname, lastname) {
return firstname + lastname;
}
function testJsAlert() {
alert("捕获js alert事件并弹出窗口");
}
- 第一个viewcontroller类,点击按钮会跳转到包含webview的view controller
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (nonatomic, strong) IBOutlet UIButton *loadWebviewButton;
@end
#import "ViewController.h"
#import "WebViewController.h"
@interface ViewController ()
@property (strong, nonatomic) WKWebView *webView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (IBAction)startLoadingWebView:(id)sender {
WebViewController *viewController = [[WebViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
}
@end
////////////////////////////////////////////
#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
@interface WebViewController : UIViewController <WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler>
@end
// 这里因为使用了弹出框,所以需要引用WKUIDelegate,因为需要实现js到objc的通信,所以需要包含WKScriptMessageHandler
#import "WebViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>
@interface WebViewController ()
@property (nonatomic, strong) WKUserContentController *controller;
@property (nonatomic, strong) WKWebView *webView;
@end
@implementation WebViewController
- (void)viewDidLoad {
[super viewDidLoad];
//首先定义了configuration,来注册js到objc的通知事件
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
WKUserContentController *weakController = [[WKUserContentController alloc] init];
self.controller = weakController;
[self.controller addScriptMessageHandler:self name:@"Login"];
[self.controller addScriptMessageHandler:self name:@"Logout"];
configuration.userContentController = self.controller;
//创建了wkwebview,记得init方法一定要把创建的config传入进去,否则消息无法派发成功。而且这里的方式不是哪self直接malloc的,防止循环引用的出现。
WKWebView *webViewT = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration];
self.webView = webViewT;
NSURL *baseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
NSString * htmlPath = [[NSBundle mainBundle] pathForResource:@"demo"
ofType:@"html"];
NSString * htmlCont = [NSString stringWithContentsOfFile:htmlPath
encoding:NSUTF8StringEncoding
error:nil];
[self.webView loadHTMLString:htmlCont baseURL:baseURL];
self.webView.navigationDelegate = self;
self.webView.UIDelegate = self;
[self.view addSubview:self.webView];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
//记得在使用了add方法添加messagehandler后一定要记得在不用的地方调用remove释放内存资源,否则内存泄露!
[self.controller removeScriptMessageHandlerForName:@"Login"];
[self.controller removeScriptMessageHandlerForName:@"Logout"];
}
- (void)dealloc {
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
NSLog(@"didStartProvisionalNavigation");
}
// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
NSLog(@"didCommitNavigation");
}
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
NSLog(@"didFinishNavigation");
//wkwebview objc 调用js 这里只能把单独的js文件以src的形式放到html文件中,然后调用具体的方法即可
[self.webView evaluateJavaScript:@"hello('lisa', 'liu')" completionHandler:^(id item, NSError * error) {
NSLog(@"the return message is %@", item);
}];
}
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation {
NSLog(@"didFailProvisionalNavigation");
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
//js调用native的处理地方。我们可以根据name和body,进行桥协议的处理。
NSString *messageName = message.name;
if ([@"Login" isEqualToString:messageName]) {
[self loginButtonSelectedWithMessageBody:message];
}
if (([@"Logout" isEqualToString:messageName])) {
[self logoutButtonSelectedWithMessageBody:message];
}
}
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
//wkwebview 默认情况下是禁止js弹出alert框体的,如果想弹出就必须要复写此功能,而且在弹出框体的时候,需要用如下的方式,completionHandler();否则在创建了alertview的同时立即调用completion会造成crash
UIAlertController* alert = [UIAlertController alertControllerWithTitle:
NSLocalizedString(@"Test Alert", nil) message: message
preferredStyle: UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle: @"OK"
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
completionHandler();
}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
}
- (void)loginButtonSelectedWithMessageBody:(WKScriptMessage *)message {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:
NSLocalizedString(@"Login", nil) message: message.body
preferredStyle: UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:cancelAction];
[self presentViewController:alert animated:YES completion:nil];
//调用完以后可以再次将想要的输出结果传回给js
NSString *jsStr = [NSString stringWithFormat:@"hello('%@','%@')",message.name, message.body];
[self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {
NSLog(@"----%@",result);
}];
}
- (void)logoutButtonSelectedWithMessageBody:(WKScriptMessage *)message {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:
NSLocalizedString(@"Logout", nil) message: message.body
preferredStyle: UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:cancelAction];
[self presentViewController:alert animated:YES completion:nil];
}
@end