Repository navigation
Expand file tree
/
Copy pathWKViewController.m
More file actions
120 lines (101 loc) · 4.28 KB
/
Copy pathWKViewController.m
File metadata and controls
120 lines (101 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//
// WKViewController.m
// WKJavaScriptBridge
//
// Created by GitWangKai on 09/14/2020.
// Copyright (c) 2020 GitWangKai. All rights reserved.
//
#import "WKViewController.h"
#import <WebKit/WebKit.h>
#import "WKJavaScriptBridge.h"
@interface WKViewController ()<WKNavigationDelegate, WKUIDelegate>
@property (nonatomic, strong) WKJavaScriptBridge *bridge;
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) WKProcessPool *processPool;
@property (nonatomic, assign, getter=loadFinished) BOOL isLoadFinished;
@end
@implementation WKViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.isLoadFinished = NO;
/*
由于WKWebView在请求过程中用户可能退出界面销毁对象,当请求回调时由于接收处理对象不存在,造成Bad Access crash,所以可将WKProcessPool设为单例
*/
static WKProcessPool *_sharedWKProcessPoolInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedWKProcessPoolInstance = [[WKProcessPool alloc] init];
});
self.processPool = _sharedWKProcessPoolInstance;
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
WKPreferences *preferences = [WKPreferences new];
preferences.javaScriptCanOpenWindowsAutomatically = YES;
preferences.minimumFontSize = 40.0;
configuration.preferences = preferences;
configuration.processPool = self.processPool;
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
self.webView = webView;
webView.navigationDelegate = self;
// [self addUserScript:webView];
/***/
self.bridge = [WKJavaScriptBridge bindBridgeWithWebView:webView];
/***/
[self.view addSubview:webView];
/*
//解决首个请求cookie带不上的问题可以使用如下方式
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@""]];
[WKWebViewCookieMgr syncRequestCookie:request];
[webView loadRequest:request];
*/
NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil];
NSURL *fileURL = [NSURL fileURLWithPath:urlStr];
if (@available(iOS 9.0, *)) {
[webView loadFileURL:fileURL allowingReadAccessToURL:fileURL];
} else {
// Fallback on earlier versions
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
/*
解决调用系统相机等产生白屏,导致内存紧张,WebContent Process 被系统挂起,此时不会执行webViewWebContentProcessDidTerminate:函数
*/
if (!self.webView.title) {
[self.webView reload];
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.isLoadFinished = YES;
}
#pragma mark - WKNavigationDelegate
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
/*
解决内存过大引起的白屏问题
*/
[webView reload];
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
/*
//如果是302重定向请求,此处拦截带上cookie重新request
NSMutableURLRequest *newRequest = [WKWebViewCookieMgr newRequest:navigationAction.request];
[webView loadRequest:newRequest];
*/
decisionHandler(WKNavigationActionPolicyAllow);
}
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
//解决window.alert() 时 completionHandler 没有被调用导致崩溃问题
if (!self.isLoadFinished) {
completionHandler();
return;
}
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { completionHandler(); }]];
if (self)
[self presentViewController:alertController animated:YES completion:^{}];
else
completionHandler();
}
@end