【问题标题】:How to Migrate to WKWebView?如何迁移到 WKWebView?
【发布时间】:2014-09-04 12:09:54
【问题描述】:

我正在尝试了解如何在 iOS8 中使用新的 WKWebView,找不到太多信息。我读过:

http://developer.telerik.com/featured/why-ios-8s-wkwebview-is-a-big-deal-for-hybrid-development/ http://nshipster.com/wkwebkit/

但这对现有应用有何影响?普通的 UiWebView 会从 nitro java 脚本引擎获得加速还是我们需要进行更改?我们如何处理向后兼容性?

我能找到的所有代码和示例都使用 swift,这是强制性的吗?

感谢您在此问题上的任何帮助!

【问题讨论】:

标签: uiwebview ios8 wkwebview


【解决方案1】:

UIWebView 仍将继续使用现有应用程序。 WKWebViewiOS8 开始可用,只有 WKWebView 有 Nitro JavaScript 引擎。

要在旧版应用程序中利用这个更快的 JavaScript 引擎,您必须更改代码以使用 WKWebView 而不是 UIWebView。对于iOS7 及更早版本,您必须继续使用UIWebView,因此您可能必须检查iOS8,然后应用WKWebView 方法/委托方法并回退到UIWebView 方法iOS7 及更早版本. WKWebView 还没有 Interface Builder 组件,因此您必须以编程方式实现 WKWebView

你可以在 Objective-C 中实现WKWebView,这里是一个简单的例子来启动WKWebView

WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:theConfiguration];
webView.navigationDelegate = self;
NSURL *nsurl=[NSURL URLWithString:@"http://www.apple.com"];
NSURLRequest *nsrequest=[NSURLRequest requestWithURL:nsurl];
[webView loadRequest:nsrequest];
[self.view addSubview:webView];

WKWebView 渲染性能在 WebGL 游戏和运行复杂 JavaScript 算法的东西中很明显,如果您使用 webview 加载简单的 html 或网站,您可以继续使用UIWebView

这是一个测试app,可用于使用UIWebViewWKWebView 打开任何网站,您可以比较性能,然后决定升级您的应用以使用WKWebViewhttps://itunes.apple.com/app/id928647773?mt=8&at=10ltWQ

【讨论】:

  • 还要考虑这一点,使用一种技术在 iOS 8 上使用 WKWebView 并在 iOS 7 上回退到 UIWebView 可能会遇到 AppStore 验证问题stackoverflow.com/questions/25897123/…
  • 请注意:需要在info.plist 中使用NSAppTransportSecurityNSAllowsArbitraryLoads 才能工作。
  • 现在无法使用UIWebView,不能在使用它的商店推送应用
【解决方案2】:

这是我从 UIWebView 转换到 WKWebView 的方法。

注意:没有像 UIWebView 这样的属性可以拖到你的 故事板,你必须以编程方式完成。

确保将 WebKit/WebKit.h 导入头文件。

这是我的头文件:

#import <WebKit/WebKit.h>

@interface ViewController : UIViewController

@property(strong,nonatomic) WKWebView *webView;
@property (strong, nonatomic) NSString *productURL;

@end

这是我的实现文件:

#import "ViewController.h"

@interface ViewController ()

@end


@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.productURL = @"http://www.URL YOU WANT TO VIEW GOES HERE";

    NSURL *url = [NSURL URLWithString:self.productURL];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    _webView = [[WKWebView alloc] initWithFrame:self.view.frame];  
    [_webView loadRequest:request];
    _webView.frame = CGRectMake(self.view.frame.origin.x,self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
    [self.view addSubview:_webView];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

【讨论】:

  • 如何加载本地文件?我试过了,但页面上什么也没出现。还有什么是像 UIWebview 这样的委托方法。例如:didloadRequest
  • 请注意:需要在info.plist 中使用NSAppTransportSecurityNSAllowsArbitraryLoads 才能工作。
  • 我复制了你上面的代码。我尝试了几个通常在浏览器中工作的 URL。视图中没有显示任何内容。可能缺少什么?
【解决方案3】:

步骤:1webkit 导入ViewController.swift

import WebKit

步骤:2声明webView的变量。

var webView : WKWebView!

步骤:3添加WKNavigationDelegate的代表

class ViewController: UIViewController , WKNavigationDelegate{

步骤:4ViewDidLoad中添加代码。

let myBlog = "https://iosdevcenters.blogspot.com/"
let url = NSURL(string: myBlog)
let request = NSURLRequest(URL: url!)

// init and load request in webview.
webView = WKWebView(frame: self.view.frame)
webView.navigationDelegate = self
webView.loadRequest(request)
self.view.addSubview(webView)
self.view.sendSubviewToBack(webView)

步骤:5编辑info.plist添加

<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>google.com</key>
<dict>
    <key>NSExceptionAllowsInsecureHTTPLoads</key>
    <true/>
    <key>NSIncludesSubdomains</key>
    <true/>
</dict>
</dict>

【讨论】:

  • 如何在 wekwebview 中保存 cookie
  • 请注意:需要在info.plist 中使用NSAppTransportSecurityNSAllowsArbitraryLoads 才能工作。
  • @KiritModi 如何在 wkwebview 中保存 cookie,我面临注销问题(会话已过期),请评论
  • @ShobhakarTiwari:看到这个stackoverflow.com/questions/26573137/…
  • @kirtimali 您无法从 wkwebview 到 ios 10 读取仅 http cookie。但是在 ios 11 中,苹果引入了新的 API 来从 wkwebview developer.apple.com/documentation/webkit/…读取 cookie
【解决方案4】:

Swift 不是必需的,Objective-C 一切正常。 UIWebView 将继续得到支持,所以如果你想慢慢来,不要急于迁移。但是,它不会获得 WKWebView 的 javascript 和滚动性能增强。

为了向后兼容,我的视图控制器有两个属性:UIWebView 和 WKWebView。仅当类存在时,我才使用 WKWebview:

if ([WKWebView class]) {
    // do new webview stuff
} else {
    // do old webview stuff
}

虽然我以前有一个 UIWebViewDelegate,但我还把它做成了一个 WKNavigationDelegate 并创建了必要的方法。

【讨论】:

  • 使用[WKWebView类]做运行时检查是一个很好的点,比检查iOS版本号要好很多。
  • 仅供参考,你能提到 wkwebview 哪个版本不可用吗?似乎从 ios 8 开始可用,因此不需要添加此检查和冗余代码。
【解决方案5】:

根据Apple docs,WkWebView 比 UIWebview 更快更可靠。 在这里,我发布了我的 WkWebViewController。

import UIKit
import WebKit

class WebPageViewController: UIViewController,UINavigationControllerDelegate,UINavigationBarDelegate,WKNavigationDelegate{

    var webView: WKWebView?
    var webUrl="http://www.nike.com"

    override func viewWillAppear(animated: Bool){
        super.viewWillAppear(true)
        navigationController!.navigationBar.hidden = false

    }
    override func viewDidLoad()
    {
        /* Create our preferences on how the web page should be loaded */
        let preferences = WKPreferences()
        preferences.javaScriptEnabled = false

        /* Create a configuration for our preferences */
        let configuration = WKWebViewConfiguration()
        configuration.preferences = preferences

        /* Now instantiate the web view */
        webView = WKWebView(frame: view.bounds, configuration: configuration)

        if let theWebView = webView{
            /* Load a web page into our web view */
            let url = NSURL(string: self.webUrl)
            let urlRequest = NSURLRequest(URL: url!)
            theWebView.loadRequest(urlRequest)
            theWebView.navigationDelegate = self
            view.addSubview(theWebView)

        }


    }
    /* Start the network activity indicator when the web view is loading */
    func webView(webView: WKWebView,didStartProvisionalNavigation navigation: WKNavigation){
            UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    }

    /* Stop the network activity indicator when the loading finishes */
    func webView(webView: WKWebView,didFinishNavigation navigation: WKNavigation){
            UIApplication.sharedApplication().networkActivityIndicatorVisible = false
    }

    func webView(webView: WKWebView,
        decidePolicyForNavigationResponse navigationResponse: WKNavigationResponse,decisionHandler: ((WKNavigationResponsePolicy) -> Void)){
            //print(navigationResponse.response.MIMEType)
            decisionHandler(.Allow)

    }
    override func didReceiveMemoryWarning(){
        super.didReceiveMemoryWarning()
    }

}

【讨论】:

    【解决方案6】:

    在 iOS 8 中使用 Swift 的 WKWebView..

    整个 ViewController.swift 文件现在看起来像这样:

    import UIKit
    import WebKit
    
    class ViewController: UIViewController {
    
        @IBOutlet var containerView : UIView! = nil
        var webView: WKWebView?
    
        override func loadView() {
            super.loadView()
    
            self.webView = WKWebView()
            self.view = self.webView!
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            var url = NSURL(string:"http://www.kinderas.com/")
            var req = NSURLRequest(URL:url)
            self.webView!.loadRequest(req)
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    
    }
    

    【讨论】:

      【解决方案7】:

      使用一些设计模式,可以混合使用 UIWebView 和 WKWebView。 关键是要设计一个独特的浏览器界面。 但是你应该更多地关注你的应用程序当前的功能, 例如:如果你的应用程序使用 NSURLProtocol 来增强网络能力,使用 WKWebView 你就没有机会做同样的事情。由于 NSURLProtocol 只影响当前进程,而 WKWebView 采用多进程架构,网络人员处于一个单独的进程中。

      【讨论】:

        【解决方案8】:

        您必须使用 WKWebView,它在 iOS8 框架“WebKit”中可用以获得加速。 如果您需要向后兼容,则必须使用适用于 iOS7 及更早版本的 UIWebView。

        我设置了一些代码来为新的 WKWebView 提供 UIViewController 框架。它可以通过 cocoapods 安装。看看这里:

        STKWebKitViewController on github

        【讨论】:

          【解决方案9】:

          斯威夫特 4

              let webView = WKWebView()   // Set Frame as per requirment, I am leaving it for you
              let url = URL(string: "http://www.google.com")!
              webView.load(URLRequest(url: url))
              view.addSubview(webView)
          

          【讨论】:

            猜你喜欢
            • 2016-09-27
            • 2016-07-12
            • 1970-01-01
            • 1970-01-01
            • 2018-09-14
            • 1970-01-01
            • 1970-01-01
            • 2018-02-20
            • 2020-05-10
            相关资源
            最近更新 更多