[iOS]WKWebView的使用
程序员文章站
2022-03-20 17:00:33
...
demo:https://download.csdn.net/download/u012881779/10928927
使用WKWebView加载H5,并与之进行一些交互。
[GABaseWKWebView]
#import "GABaseWKWebView.h"
@implementation GABaseWKWebView
- (instancetype)init {
self = [super init];
if (self) {
[self setUserAgentInfo];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setUserAgentInfo];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame configuration:(nonnull WKWebViewConfiguration *)configuration {
self = [super initWithFrame:frame configuration:configuration];
if (self) {
[self setUserAgentInfo];
}
return self;
}
- (void)setUserAgentInfo {
// userAgent设置
[self evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error) {
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSString *appVer = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
NSString *oldAgent = result;
NSString *newAgent;
// 给User-Agent添加额外的信息 - 区分来自哪个app
if ([oldAgent containsString:@"appmark"]) {
newAgent = oldAgent;
} else {
newAgent = [NSString stringWithFormat:@"%@;AppInfo:appName=%@&&appVer=%@", oldAgent, @"appmark", appVer];
}
// 设置global User-Agent
if (@available(iOS 9.0, *)) {
[self setCustomUserAgent:newAgent];
}
}];
}
@end
[GABaseWKWebViewController]
#import "GABaseWKWebViewController.h"
#import <WebKit/WebKit.h>
#import "GABaseWKWebView.h"
@interface GABaseWKWebViewController () <WKNavigationDelegate, WKScriptMessageHandler>
@property (strong, nonatomic) GABaseWKWebView *webView;
@property (strong, nonatomic) NSArray *nameMArr;
@property (nonatomic, strong) NSString *loadUrl;
@end
@implementation GABaseWKWebViewController
- (void)dealloc {
_loadUrl = nil;
_webView = nil;
_nameMArr = nil;
}
- (void)viewDidLoad {
[super viewDidLoad];
if (!_webView) {
_webView = [[GABaseWKWebView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
_webView.navigationDelegate = self;
}
[self.view addSubview:_webView];
/*
链接不支持https协议时,需要去Info.plist设置允许任意加载
App Transport Security Settings
Allow Arbitrary Loads YES
*/
NSURL *pathUrl = [self handleLoadUrl:_loadUrl];
[_webView loadRequest:[NSURLRequest requestWithURL:pathUrl]];
}
- (NSURL *)handleLoadUrl:(NSString *)urlString {
// 处理url带有中文的
NSString *encodedString = (NSString*) CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)urlString,(CFStringRef)@"!$&'()*+,-./:;[email protected]_~%#[]",NULL, kCFStringEncodingUTF8));
NSURL *url = [NSURL URLWithString:encodedString];
return url;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self addScriptAction];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self removeScriptAction];
}
// 注入JavaScript与原生交互协议
// JS 端可通过 window.webkit.messageHandlers.<name>.postMessage(<messageBody>) 发送消息
- (void)addScriptAction {
if (!_nameMArr) {
_nameMArr = [[NSArray alloc] initWithObjects:@"goHomeIos",@"sharePagesIos",@"getUserInfoIos",nil];
}
for (NSString *subName in _nameMArr) {
[_webView.configuration.userContentController addScriptMessageHandler:self name:subName];
}
}
// 移除注入的协议
- (void)removeScriptAction {
if (_nameMArr) {
for (NSString *subName in _nameMArr) {
[_webView.configuration.userContentController removeScriptMessageHandlerForName:subName];
}
}
}
#pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
NSLog(@"开始加载");
}
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {
NSLog(@"内容开始返回");
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
NSLog(@"加载完成");
}
- (void)webView:(WKWebView *)webView didFailLoadWithError:(nonnull NSError *)error {
NSLog(@"加载失败 error : %@",error.description);
}
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if (navigationAction.targetFrame == nil) {
[webView loadRequest:navigationAction.request];
}
NSURL *URL = navigationAction.request.URL;
NSString *urlPath = [URL absoluteString];
NSString *scheme = [URL scheme];
NSString *resourceSpecifier = [URL resourceSpecifier];
if ([scheme isEqualToString:@"tel"]) {
NSString *callPhone = [NSString stringWithFormat:@"telprompt://%@", resourceSpecifier];
// 防止iOS 10及其之后,拨打电话系统弹出框延迟出现
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:callPhone]];
});
decisionHandler(WKNavigationActionPolicyCancel);
} else if ([scheme isEqualToString:@"mqq"]) {
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"mqq://"]]) {
NSString *callQQ = [NSString stringWithFormat:@"mqq://%@", resourceSpecifier];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:callQQ]];
});
}
decisionHandler(WKNavigationActionPolicyCancel);
} else if ([scheme isEqualToString:@"mailto"]) {
NSString *callEmail = [NSString stringWithFormat:@"mailto://%@", resourceSpecifier];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:callEmail]];
});
decisionHandler(WKNavigationActionPolicyCancel);
} else {
decisionHandler(WKNavigationActionPolicyAllow);
}
}
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
decisionHandler(WKNavigationResponsePolicyAllow);
}
#pragma mark - 执行JavaScript代码
- (void)loadJs:(NSString *)js {
// ios11要求evaluateJavaScript主线程
dispatch_async(dispatch_get_main_queue(), ^{
[self.webView evaluateJavaScript:js completionHandler:^(id _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"evaluateJavaScript error = %@\n", error);
}
}];
});
}
#pragma mark - WKScriptMessageHandler
/*
在协议方法中获取JavaScript端传递的事件和参数
WKScriptMessage
name 协议名称
body 传递的参数
*/
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"body:%@", message.body);
NSLog(@"message.name = %@",message.name);
NSString *name = message.name;
if ([name isEqualToString:@"goHomeIos"]) {
// 首页
} else if ([name isEqualToString:@"sharePagesIos"]) {
// 分享
} else if ([message.name isEqualToString:@"getUserInfoIos"]) {
// 获取用户信息
[self getUsrInfo];
}
}
- (void)getUsrInfo {
NSString *usrId = @"UserID";
NSString *token = @"Token";
NSString *identity = @"Identity";
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:token,@"token", identity,@"identity", usrId,@"userId", nil];
NSString *jsBody = [self dictionaryToJson:dic];
NSString *js = [NSString stringWithFormat:@"javascript:vueObj.getUserInfoPage('%@')", jsBody];
[self loadJs:js];
}
- (NSString *)dictionaryToJson:(NSDictionary *)dic {
if (dic == nil) {
return @"";
}
NSError *parseError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&parseError];
NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
jsonStr = [jsonStr stringByReplacingOccurrencesOfString:@"\n" withString:@""];
jsonStr = [jsonStr stringByReplacingOccurrencesOfString:@" " withString:@""];
jsonStr = [jsonStr stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"];
return jsonStr;
}
@end
上一篇:
HTML
下一篇: python全栈工程师是什么