This is the 17th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021.

Now, the newly submitted iOS app must use WKWebView to replace UIWebView. Let’s understand the advantages of WKWebView:

  1. More support for HTML5 features
  2. Officially announced scrolling refresh rate up to 60fps and built-in gestures
  3. UIWebViewDelegate and UIWebView are split into 14 classes and 3 protocols. Many functions that were not easy to implement before can be realized
  4. Safari’s same JavaScript engine
  5. Takes up less memory

Class:

WKBackForwardList: A list of previously visited Web pages, which can be queried by backward and forward action visits. WKBackForwardListItem: a web page in the back list of the WebView. WKFrameInfo: Contains layout information for a web page. WKNavigation: contains information about the loading progress of a web page. WKNavigationAction: Contains information that might cause navigation changes to the page and is used to determine whether to make navigation changes. WKNavigationResponse: Contains information about the returned content that might change the navigation of the page, and is used to determine whether or not a navigation change has been made. WKPreferences: Outlines the preferences of a WebView. WKProcessPool: Represents a Web content loading pool. WKUserContentController: provides methods to post messages and inject scripts using JavaScript. WKScriptMessage: Contains the message sent by the web page. WKUserScript: represents a user script that can be accepted by a web page. WKWebViewConfiguration: Initializes webView Settings. WKWindowFeatures: Specifies window properties for loading a new web page.

Protocol:

WKNavigationDelegate: provides methods to track the main window page loading process and determine whether the main window and child window page loading new page.

WKScriptMessageHandler: Provides callback methods to receive messages from web pages. WKUIDelegate: Provides method callbacks for displaying web pages with native controls.

Loading way

Methods a
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
Way 2
WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc] init];

webView = [[WKWebView alloc] configuration:configuration];

[webView loadRequest:[NSURLRequest URLWithString:@"http://www.baidu.com"]]];

[self.view addSubview:webView];
Copy the code

Protocol method introduction:

WKNavigationDelegate
/ / start page load time call initWithFrame: self. The bounds requestWithURL: [NSURL - (void) webView: (webView WKWebView *) didStartProvisionalNavigation:(WKNavigation *)navigation{ }Copy the code

Called when content starts to return

-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{

}
Copy the code

Called after the page has finished loading

-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{

}
Copy the code

Called when the page load fails

-(void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{

}
Copy the code

Called after a server jump request is received

-(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{

}
Copy the code

After receiving the response, decide whether to jump

-(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{ NSLog(@"%@",navigationResponse.response.URL.absoluteString); / / allow jump decisionHandler (WKNavigationResponsePolicyAllow); / / is not allowed to jump / / decisionHandler (WKNavigationResponsePolicyCancel); }Copy the code

Before sending the request, decide whether to jump

-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{ NSLog(@"%@",navigationAction.request.URL.absoluteString); / / allow jump decisionHandler (WKNavigationActionPolicyAllow); / / is not allowed to jump / / decisionHandler (WKNavigationActionPolicyCancel); }Copy the code
WKUIDelegate

Create a new WebView

-(WKWebView*)webView:(WKWebView*)webView createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration forNavigationAction:(WKNavigationAction*)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{

return [[WKWebView alloc]init];
}
Copy the code

Input box

-(void)webView:(WKWebView*)webView runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{

completionHandler(@"http");
}
Copy the code

Confirmation box

-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{

completionHandler(YES);
}
Copy the code

Alert box

-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo  *)frame completionHandler:(void (^)(void))completionHandler{ NSLog(@"%@",message); completionHandler(); }Copy the code

OC and JS interaction

WKWebView UIDelegate provides three protocol methods that make it easy for the front end to intercept JS alert, confirm, prompt methods. In addition, OC and JS intermodulation can be performed as follows.

1. OC invokes JS

You can use the WebKit library

- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler; 
Copy the code

For example, OC calls the JS method setName

[webView evaluateJavaScript:@" setName (' zhang 3 ')" completionHandler:nil];Copy the code

Here setName is the method name defined by JS, and internal “zhang SAN” is the parameter passed to JS. If the setName method needs to pass in a non-character argument such as JSON or array, use the format method to convert it to string and then call evaluate. For example,

NSString * para = [NSString stringWithFormat:@"setname('%@')",json];
Copy the code

2. JS invokes OC

This is where WKScriptMessageHandler comes in

@property (nonatomic,strong)WKUserContentController * userCC; 1. Follow WKScriptMessageHandler protocol 2. WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc]init]; self.wkWebViw=[[WKWebView alloc]initWithFrame:self.view.bounds configuration:config]; [self.wkWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.webPageUrl]]]; [self.view addSubview:self.wkWebViw]; self.userCC = config.userContentController; [self.userCC addScriptMessageHandler:self name:@"callOSX"]; / / here is equivalent to monitor the JS callFunction this method [self. UserCC addScriptMessageHandler: self name: @ "callFunction"].Copy the code

WKScriptMessageHandler receives this message in its protocol method when JS issues the callFunction directive

#pragma mark WKScriptMessageHandler delegate - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { Message. name represents the method name (' in this case, callFunction '), message.body represents the argument passed to us by JS.Copy the code

Finally, the HANDLER must be removed when the VC is destroyed


- (void)dealloc {

    [_userContentController removeScriptMessageHandlerForName:@"callFunction"]; 
}
Copy the code

Corresponding JS code

<button onclick="buttonClick "> </button> <script> function buttonClick(string){ Format / / (window. Its. MessageHandlers. Method_Name. PostMessage (parameterToOC)) window.webkit.messageHandlers.callFunction.postMessage(string) } </script>Copy the code