Replace UIWebView with Wkwebview

Source: Internet
Author: User

I recently crashed in the iOS10 system with UIWebView loading connection.

You need to replace UIWebView with the latest Wkwebview

The following is a description of the relevant content (from the link: http://www.wangyangdev.com/2015/11/13/using Wkwebview replacement uiwebview/)

In the process of developing an app, you will often experience loading pages inside the app, usually UIWebView loaded. This web loader, which has been in use since iOS2, has been developed 心病 : loading is slow, memory is occupied, and optimization is difficult. If you load more Web pages, you may also lose the system due to excessive memory consumption kill . The effects of the various optimizations are also less obvious (click to view Common optimization methods).

After IOS8, Apple introduced a new framework Webkit that provided replacement UIWebView components WKWebView . All kinds UIWebView of problems, faster, less memory, a word, the WKWebView app is the best choice to load the page!

First look at WKWebView the following features:

    1. In the performance, stability, function has a great improvement (the most intuitive embodiment is the loading of the page is occupied memory, simulator load Baidu and open source China website, Wkwebview occupy 23M, and UIWebView occupy 85M);
    2. Allows JavaScript's nitro library to be loaded and used (limited in UIWebView);
    3. Support for more HTML5 features;
    4. Up to 60fps scrolling refresh rate and built-in gestures;
    5. Uiwebviewdelegate and UIWebView are composed of 14 classes and 3 protocols (view Apple official documents);

Then from the following aspects WKWebView of the basic usage:

    1. Loading Web pages
    2. State callback for loading
    3. The new WKUIDelegate protocol
    4. Dynamically loading and running JS code
    5. WebView JS Code Execution
    6. JSCall the app to register a method
First, load the Web page

Load the Web page or HTML code in the UIWebView same way that the code example looks like:

WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];[self.view addSubview:webView];
Second, the state callback of the load (wknavigationdelegate)

Used to track the loading process (page start load, load complete, load failed) method:

//page starts loading when called-(webview: (Wkwebview *) WebView  Didstartprovisionalnavigation: (wknavigation *) navigation; //called when content starts to return-(void) webView: ( Wkwebview *) WebView didcommitnavigation: (wknavigation *) navigation; //the page is loaded after the completion of the call-(void) webView: ( Wkwebview *) WebView didfinishnavigation: (wknavigation *) navigation; //page load failed when called-(void) webView: ( Wkwebview *) WebView didfailprovisionalnavigation: (wknavigation *) navigation;   

Proxy method for page jumps:

Called after a server jump request has been received-(void)WebView:(Wkwebview *)WebViewDidreceiveserverredirectforprovisionalnavigation:(wknavigation *)NavigationAfter receiving the response, decide whether to jump-(void)WebView:(Wkwebview *)WebViewDecidepolicyfornavigationresponse:(Wknavigationresponse *) navigationresponse decisionhandler:(void (^) (wknavigationresponsepolicy))Decisionhandler;  Before sending a request, decide whether to jump -(void)WebView:(Wkwebview *)webView decidepolicyfornavigationaction:( Wknavigationaction *)navigationaction decisionhandler:(void (^) (wknavigationactionpolicy))  Decisionhandler;               
Third, the new WKUIDelegateAgreement

This protocol is mainly used to WKWebView process the Web interface three kinds of prompt boxes (warning boxes, confirmation boxes, input boxes), the following is an example of the warning box:

/** *  web界面中有弹出警告框时调用 * *  @param webView           实现该代理的webview *  @param message           警告框中的内容 *  @param frame             主窗口 *  @param completionHandler 警告框消失调用 */- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler;
Four, dynamic loading and running JSCode

Used to add JS code to the client and execute it, as an example:

Picture-scaled JS codeNSString *js =@ "var count = Document.images.length;for (var i = 0; i < count; i++) {var image = Document.images[i];image.style.width= 320;}; Window.alert (' find ' + count + ' map ');Initializes a Wkuserscript object based on a JS stringwkuserscript *script = [[wkuserscript Alloc] InitWithSource : JS injectiontime:wkuserscriptinjectiontimeatdocumentend ForMainFrameOnly:yes]; //initializes wkuserscript Wkwebviewconfigurationwkwebviewconfiguration Alloc] init];[ Config.usercontentcontroller Adduserscript:script];_webview = [[WKWebView alloc] Initwithframe:self.view.bounds Configuration:config]; [_webview loadhtmlstring:@ "nil]; [self.view Addsubview:_webview];         
V. Implementation of WebView JSCode

The user invokes the JS code written, generally referred to by the server development:

//javaScriptString是JS方法名,completionHandler是异步回调block[self.webView evaluateJavaScript:javaScriptString completionHandler:completionHandler];
Six JSCall the app to register a method

The WKWebView method that registers for JS to call again is through WKUserContentController the following method of the class:

- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;

scriptMessageHandlerIs the proxy callback, which invokes JS name OC the specified object after the method is called scriptMessageHandler .

JSUse the OC following methods when calling the registration method:

window.webkit.messageHandlers.<name>.postMessage(<messageBody>)

Note that name (method name) is placed in the middle, messagebody can only be an object, if you want to pass multiple values, you need to encapsulate an array, or a dictionary. The entire example is as follows:

//OC注册供JS调用的方法[[_webView configuration].userContentController addScriptMessageHandler:self name:@"closeMe"];//OC在JS调用方法做的处理- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ NSLog(@"JS 调用了 %@ 方法,传回参数 %@",message.name,message.body);}//JS调用 window.webkit.messageHandlers.closeMe.postMessage(null);

If you self dealloc hit a breakpoint, you will find self no release! This is obviously not going to work! Google later saw a workaround, as follows:

@interfaceWeakscriptmessagedelegate:nsobject<Wkscriptmessagehandler>@property (Nonatomic,Weakid<Wkscriptmessagehandler> scriptdelegate;-(Instancetype) Initwithdelegate: (id<wkscriptmessagehandler>) Scriptdelegate;@end @implementation weakscriptmessagedelegate-(instancetype) Initwithdelegate: (id< wkscriptmessagehandler>) scriptdelegate{self = [super INIT]; if (self) {_scriptdelegate = scriptdelegate;} return self;} -(void) Usercontentcontroller: (wkusercontentcontroller *) Usercontentcontroller didreceivescriptmessage: (wkscriptmessage *) message{[self.scriptdelegate Usercontentcontroller:usercontentcontroller DidReceiveScriptMessage:message] ;}  @end             

The idea is to create another proxy object, which is then specified by a proxy object callback self ,

WKUserContentController *userContentController = [[WKUserContentController alloc] init];    [userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"closeMe"];

Run code, self released, WeakScriptMessageDelegate but not released AH Ah!
You also need self to dealloc add this code to the inside:

[[_webView configuration].userContentController removeScriptMessageHandlerForName:@"closeMe"];

OK, solve the problem satisfactorily!

Currently, most apps need to support iOS7 and above, but WKWebView only after iOS8, so a compatibility scheme is required, both iOS7 UIWebView and IOS8 WKWebView . This library provides this compatibility scenario: Https://github.com/wangyangcc/IMYWebView

Part of the above is referenced from: http://www.brighttj.com/ios/ios-wkwebview-new-features-and-use.html

Replace UIWebView with Wkwebview

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.