reprint: http://blog.csdn.net/u011619283/article/details/52135982original August 06, 2016 14:00:08
- Label:
- IOS/
- JavaScript/
- Wkwebview
In the previous article, we described how to handle JS and OC interactions using UIWebView blocking URLs.
Because UIWebView is more memory-intensive, the performance is not good, and Apple launched the Wkwebview in iOS 8.
The same with Wkwebview can also intercept URLs, do JS and oc interaction. On the comparison between Wkwebview and UIWebView, we ask you to automatically Baidu or Google.
before opening Baidu Web page |
after opening Baidu Web page |
UIWebView |
Memory 47M |
Wkwebview |
Memory 47M |
Wkwebview Intercept URL
Wkwebview and UIWebView intercept URLs are handled essentially the same way. In addition to the agent method and the use of Wkwebview is not quite the same, about Wkwebview more detailed explanation and usage, or self-search study, this article focuses on how to achieve JS and OC call each other.
Reminder: Wkwebview is a webkit.framework control in iOS 8 that is available only when the app does not need to be compatible with iOS 7 and below.
First look at the dynamic:
1. Create Wkwebview and load the local HTML.
There are several differences in the creation of Wkwebview:
* 1. Initialization of a configuration
parameter, of course, we can not pass this parameter, directly using the default settings is good.
* 2.WKWebView agent has two navigationDelegate
and UIDelegate
. We want to intercept the URL, it navigationDelegate
is necessary to pass a proxy method to achieve. If you want to use an alert window in HTML, you have to implement UIDelegate
the appropriate proxy method.
* 3. Before iOS 9, there are some problems with Wkwebview loading native HTML. (Cannot load local HTML, or partial css/local picture cannot load etc.)
Here's the example code that I created Wkwebview here:
Wkwebviewconfiguration *configuration = [[Wkwebviewconfiguration alloc] init]; Configuration. Usercontentcontroller = [Wkusercontentcontroller new]; Wkpreferences *preferences = [wkpreferences new]; Preferences. javascriptcanopenwindowsautomatically =YES; Preferences. minimumfontsize =30.0; Configuration. Preferences = preferences;Self. WebView = [[Wkwebview alloc] initWithFrame:Self. View.frame configuration:configuration]; NSString *urlstr = [[nsbundle Mainbundle] pathforresource:@ " Index.html "Oftype:nil]; NSURL *fileURL = [nsurl fileurlwithpath:urlstr]; [self.webview loadfileurl:fileurl allowingreadaccesstourl:fileurl]; self.webview.navigationDelegate = Span class= "Hljs-keyword" >self; [self.view Addsubview:self.webview];
Because the loaded local HTML content is the same as the HTML content described in the previous UIWebView, the content in the HTML is no longer explained.
2. Intercepting URLs
Use the proxy method in wknavigationdelegate to intercept the custom URL to implement JS calling the OC method.
#pragma mark-wknavigationdelegate-(void) WebView: (Wkwebview *) WebView decidepolicyfornavigationaction: (wknavigationaction *) navigationaction Decisionhandler: (void (^) (wknavigationactionpolicy)) decisionhandler{ nsurl *url = navigationaction. Request. URL; nsstring *scheme = [URL scheme]; if ([Scheme isequaltostring:@"Haleyaction"]) {[selfhandlecustomaction:url]; Decisionhandler (Wknavigationactionpolicycancel); return; } decisionhandler (Wknavigationactionpolicyallow);}
It is important to note that:
1. If you implement this proxy method, you must call decisionHandler
this block, otherwise it will cause the app to crash. The block parameter is an enumeration type that WKNavigationActionPolicyCancel
represents an undo load, which is equivalent to the UIWebView proxy method return No, and represents the case where the load is allowed, which is equivalent to the WKNavigationActionPolicyAllow
return Yes in the proxy method of UIWebView.
2. Other information about why the scheme should be set uniformly, as mentioned in the previous article.
about how to differentiate between executing different OC methods, as well as the way UIWebView is handled, the host of the URL distinguishes between different methods of execution:
#pragma mark-private method-(void) Handlecustomaction: (Nsurl *) url{NSString *host = [URL host];if ([Host isequaltostring:@"Scanclick"]) {NSLog (@"Sweep"); }Elseif ([Host isequaltostring:@"Shareclick"]) {[Self Share:url]; }Elseif ([Host isequaltostring:@"GetLocation"]) {[Self getLocation]; }else if ([Host Isequaltostring:@ " SetColor "]) { [self changebgcolor:url]; } else if ([Host Isequaltostring:@ "payAction"] ) { [self payaction:url]; } else if ([Host Isequaltostring:@" shake "]) { [self shakeaction]; } else if ([Host Isequaltostring:@ "GoBack"]) { [ Span class= "Hljs-keyword" >self goback]; }}
3.OC Call JS method
After JS calls the OC method, some operations may need to return the results to JS. This is the scenario where OC invokes the JS method.
Wkwebview provides a new way evaluateJavaScript:completionHandler:
to implement OC Invoke JS and other scenarios.
- (void)getLocation{ // 获取位置信息 // 将结果返回给js NSString *jsStr = [NSString stringWithFormat:@"setLocation(‘%@‘)",@"广东省深圳市南山区学府路XXXX号"]; [self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) { NSLog(@"%@----%@",result, error); }];}
evaluateJavaScript:completionHandler:
There is no return value, JS execution succeeds or the failure is returned in Completionhandler. So use this API to avoid time-consuming JS, or alert causes the interface to stuck problems.
Using pop-up windows in 4.WKWebView
As mentioned above, if you use alert, confirm and other pop-up windows in Wkwebview, you have to implement the WKUIDelegate
corresponding proxy method in Wkwebview.
For example, in JS I want to display the alert pop-up window, you must implement the following proxy method, otherwise alert will not pop up.
#pragma mark-wkuidelegate-(void) WebView: (Wkwebview *) WebView runjavascriptalertpanelwithmessage: (nsstring *) message Initiatedbyframe :(Wkframeinfo *) frame completionhandler: (void (^) (void)) completionhandler{Uialertcontroller *alert = [ Uialertcontroller alertcontrollerwithtitle:@"remind" Message:message Preferredstyle:uialertcontrollerstylealert]; [Alert addaction:[uialertaction actionwithtitle:@"Know" Style:uialertactionstylecancel handler:^ (UIAlertAction * _nonnull action) {Completionhandler (); }]]; [Selfpresentviewcontroller:alert animated:YES Completion:nil];}
Where completionHandler
this block must be called, as to where to invoke, it does not matter, we can also write in the method implementation of the first line, or the last line.
Example Project address: Js_oc_url
Wkwebview Intercept URL