Why WKWebView
In the process of App development, it is inevitable to use web page loading. Since iOS2, we have been using UIWebView loading, which has a slow loading speed, takes up a lot of memory, and is difficult to optimize. If it loads too many web pages, it may be killed by the system because of excessive memory consumption.
After iOS8, Apple launched WebKit, which provides the component WKWebView to replace UIWebView. There is no doubt that WKWebView will gradually replace the bulky UIWebView.
WKWebView new features
- In the performance, stability, function has a great improvement, the web page loading speed, less memory
- Support for more HTML5 features
- Same JavaScript engine as Safari
- Officially announced scrolling refresh rate up to 60fps and built-in gestures
- Add the load progress attribute: estimatedProgress
- Refactoring UIWebViewDelegate and UIWebView into 14 classes and 3 protocols (see Apple documentation);
WKWebView instructions
There are two initialization methods (remember to import #import<WebKit/WebKit.h>
)
// Default initialization
- (instancetype)initWithFrame:(CGRect)frame;
// Initialize the webView according to the related configuration
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
Copy the code
Load web pages and HTML code in the same way as UIWebView
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
[self.view addSubview:webView];
Copy the code
Page navigation Refreshes related properties and methods
// Can I back up
@property (nonatomic.readonly) BOOL canGoBack;
// Whether can forward
@property (nonatomic.readonly) BOOL canGoForward;
// Whether it is loading
@property (nonatomic.readonly) BOOL loading;
// Load progress. Value: 0 or 1
@property (nonatomic.readonly) double estimatedProgress;
// Whether to allow left and right gesture navigation
@property (nonatomic) BOOL allowsBackForwardNavigationGestures;
// WKBackForwardList type to access the history list, which can be accessed through the forward and back buttons, or by jumping to the specified page through the goToBackForwardListItem function
@property (nonatomic.readonly.strong) WKBackForwardList *backForwardList;
/ / refresh
- (WKNavigation *)reload;
// Stop loading
- (void)stopLoading;
// the back function
- (WKNavigation *)goBack;
// forward function
- (WKNavigation *)goForward;
// If there is no change in the network data, use the cache, otherwise a new request.
- (WKNavigation *)reloadFromOrigin;
// Jumps to a specified history page
- (WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)item;
Copy the code
WKWebView proxy method
1.WKNavigationDelegate
The agent provides methods that can be used to track the loading process (the page starts loading, the page finishes loading, the page fails) and decide whether to perform a jump.
Methods to track the loading process (page start, page finish, and page failure) :
// called when the page starts loading
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
// Called when content starts to return
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// called after the page has finished loading
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// called when page load fails
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
Copy the code
Proxy method for page jump:
// called after a server jump request is received
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
// After receiving the response, decide whether to jump
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void(^) (WKNavigationResponsePolicy))decisionHandler;
// Before sending the request, decide whether to jump
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void(^) (WKNavigationActionPolicy))decisionHandler;
Copy the code
2.WKUIDelegate
UI interface related, native control support, three kinds of prompt box: input, confirm, warning. The Web prompt box is first blocked and then processed.
Create a new WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
/ / input box
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void(^) (NSString * __nullable result))completionHandler;
/ / confirmation box
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void(^) (BOOL result))completionHandler;
/ / alert box
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void(^) (void))completionHandler;
Copy the code
3.WKScriptMessageHandler
This protocol contains a method that must be implemented. This method is the key to improve the interaction between App and Web side. It can directly convert the JS scripts received into OC or Swift objects. Provides callback methods to receive messages from a web page.
// Called when a script is received from the Web interface
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
Copy the code
tip
- Adaptive screen width
NSString *jScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
WKUserContentController *wkUController = [[WKUserContentController alloc] init];
[wkUController addUserScript:wkUScript];
WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
wkWebConfig.userContentController = wkUController;
_web1 = [[WKWebView alloc] initWithFrame:CGRectNull configuration:wkWebConfig];
Copy the code
- Get page height
#pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
[webView evaluateJavaScript:@"document.body.offsetHeight" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
_webHeight = [result doubleValue];
}];
}
Copy the code
- Picture adaptive device width
NSString *js = @"function imgAutoFit() { \ var imgs = document.getElementsByTagName('img'); \ for (var i = 0; i < imgs.length; ++i) {\ var img = imgs[i]; \ img.style.maxWidth = %f; \} \}";
js = [NSString stringWithFormat:js, [UIScreen mainScreen].bounds.size.width - 20];
WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:js injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
WKUserContentController *wkUController = [[WKUserContentController alloc] init];
[wkUController addUserScript:wkUScript];
WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
wkWebConfig.userContentController = wkUController;
_webView = [[WKWebView alloc] initWithFrame:CGRectMake(0.64, qScreenWidth, qScreenHeight - 64) configuration:wkWebConfig];
Copy the code
- Loading local Web pages
NSURL * url = [[NSBundle mainBundle] URLForResource:@"fuwutiaokuan.html" withExtension:nil];
[self.wkWebView loadRequest:[NSURLRequest requestWithURL:url]];
Copy the code
Reference content:
Replace UIWebView with WKWebView
UIWebView, WKWebView usage and performance analysis
Use of WKWebView and various pit solutions (OC+Swift)