Xcode 9 GM-WKWebView NSCoding 支持在以前的版本中被打破

有人知道如何修复这个错误与 Xcode 9通用汽车?我正在开发一个用 Xcode 8.3开发的应用程序,部署目标是 iOS 9.3,我以前从来没有遇到过这个问题。我还没有在这里或苹果论坛上找到任何信息:

编辑: 这个错误出现在我把一个 WKWebView 放入 Interface Builder 时,而不是如果我以编程方式使用它。

See picture WKWebView Error

编辑2: 好吧,这终于不是一个错误,看奎因的答案下面有更多的信息关于这种行为。谢谢他的解释。

66649 次浏览

UIWebView 在 iOS11中不被推荐使用,WKWebView 只能在 iOS11中使用——这听起来像是 Xcode GM 中的 bug。

这似乎是 Xcode 9中的一个 bug,也出现在 beta 版本中。只有通过故事板创建 WKWebView 时才会出现构建错误。如果您以编程方式在相应的 ViewController 类文件中创建 WKWebView,那么您应该能够在 iOS11以下的 iOS 版本上进行构建。 以下是苹果网站上给出的实现方法:

import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate {


var webView: WKWebView!


override func loadView() {
super.loadView()
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()


let myURL = URL(string: "https://www.apple.com")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}}

然后,您应该能够像通常那样实现 WKWebView 功能。

资料来源: https://developer.apple.com/documentation/webkit/wkwebview

错误是正确的行为,而不是 Xcode 9中的 bug。虽然 wkWebView 是在 ios8中引入的,但是在 -[WKWebView initWithCoder:]中有一个只在 ios11中修复的 bug,它总是在运行时崩溃,因此无法在 Interface Builder 中配置。

Https://bugs.webkit.org/show_bug.cgi?id=137160

它不是允许开发人员在 IB 中构建在运行时会被破坏的内容,而是一个构建错误。这是一个不方便的限制,因为 iOS11只是最近才发布,但实际上没有其他好的选择。

老部署目标的解决方案是继续在代码中添加 WKWebView,正如@fahad-ashraf 在他的回答中所描述的:

Https://developer.apple.com/documentation/webkit/wkwebview

如果你想实现一个包含其他组件的 定制 UIViewController,你可以通过故事板制作一个“容器”,例如 webViewContainer:

import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate {
@IBOutlet weak var webViewContainer: UIView!
var webView: WKWebView!
    

override func viewDidLoad() {
super.viewDidLoad()
let webConfiguration = WKWebViewConfiguration()
let customFrame = CGRect.init(origin: CGPoint.zero, size: CGSize.init(width: self.webViewContainer.frame.size.width, height: self.webViewContainer.frame.size.height))
self.webView = WKWebView (frame: customFrame , configuration: webConfiguration)
webView.translatesAutoresizingMaskIntoConstraints = false
self.webViewContainer.addSubview(webView)
webView.topAnchor.constraint(equalTo: webViewContainer.topAnchor).isActive = true
webView.rightAnchor.constraint(equalTo: webViewContainer.rightAnchor).isActive = true
webView.leftAnchor.constraint(equalTo: webViewContainer.leftAnchor).isActive = true
webView.bottomAnchor.constraint(equalTo: webViewContainer.bottomAnchor).isActive = true
webView.heightAnchor.constraint(equalTo: webViewContainer.heightAnchor).isActive = true
webView.uiDelegate = self
        

let myURL = URL(string: "https://www.apple.com")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}

我也遇到过同样的问题,但是如果我们以编程方式添加 WKWebView,就可以解决这个问题。

  1. 在情节串连板中做任何你想要做的设计,但是离开房间给 WKWebView,在那个区域拖放一个视图并将其命名为 WebViewContainer,然后声明这两个属性,

    @property (weak, nonatomic) IBOutlet UIView *webViewContainer;
    @property(nonatomic, strong)WKWebView *webView;
    
  2. Now create and add webView like this:

    -(instancetype)initWithCoder:(NSCoder *)aDecoder
    {
    self.webView = [self createWebView];
    self = [super initWithCoder:aDecoder];
    return self;
    }
    

    CreateWebView 函数声明为,

    -(WKWebView *)createWebView
    {
    WKWebViewConfiguration *configuration =
    [[WKWebViewConfiguration alloc] init];
    return [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
    }
    
  3. Now add this newly created webView to your containerView, like this, :

    -(void)addWebView:(UIView *)view
    {
    [view addSubview:self.webView];
    [self.webView setTranslatesAutoresizingMaskIntoConstraints:false];
    self.webView.frame = view.frame;
    }
    
  4. Finally, just load your Url like this,

    -(void)webViewLoadUrl:(NSString *)stringUrl
    {
    NSURL *url = [NSURL URLWithString:stringUrl];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];
    }
    

Thanks for reading this.

如果您从旧的目标移动到 iOS 11.0,但仍然得到这个错误,那么使用下面的解决方案。

  1. 进入情节串连板(Main.Storyboard) ,点击任意场景。
  2. 选择“文件检查器”,它是 Xcode 的右侧属性窗口
  3. 将‘ 建造’值更改为‘ IOS 11.0及其后版本
  4. 编译和构建

enter image description here

WebKit 是在 IOS8中引入的,但它发布时出现了一个错误,导致运行时崩溃。如果你使用的是 Xcode 9/10,你的项目配置支持小于 IOS11,如果你试图使用 Interface Builder 添加 WKWebView。Xcode 立即显示编译时错误。

在 iOS 11.0之前的 WKWebView (NSCoding Support 在之前的版本中被破坏了)

虽然 WKWebView 是在 IOS8中引入的,但是在-[ WKWebView initWithCoder: ]中有一个错误,这个错误只在 IOS11中修复了。

enter image description here

解决方案是你必须通过代码添加 WKWebView (只有当你支持 iOS11以下版本时)。

另一个解决方案 是将文档构建的 Interface Builder 更改为 iOS 11或更高版本(如果你从旧版本目标迁移到 iOS 11,仍然得到相同的错误)。

//致 Swift

import WebKit


class ViewController: UIViewController {
var webView: WKWebView!


// MARK:- WebView Configure
override func loadView() {
let webConfig = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfig)
view = webView
}




override func viewDidLoad() {
super.viewDidLoad()
// call urlrequest fun
loadURLRequest()
}


//MARK:- Webview URLRequest
func loadURLRequest()  {
let urlString = "https://www.google.com"
let url = URL(string: urlString)
let urlRequest = URLRequest(url: url!)
webView.load(urlRequest)
}
}

//目标 C

#import <WebKit/WebKit.h>


@interface ViewController ()<WKNavigationDelegate,WKUIDelegate>{
WKWebView *webView;
}


@end


@implementation ViewController


- (void)viewDidLoad {
[super viewDidLoad];
    

NSURL *url = [[NSURL alloc] initWithString: @"https://www.google.com"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
[webView loadRequest: request];
}




- (void)loadView {
[super loadView];


WKWebViewConfiguration *configu = [[WKWebViewConfiguration alloc] init];
webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configu];
webView.UIDelegate = self;
self.view = webView;
}


@end

enter image description here

import UIKit
import WebKit


class ViewController: UIViewController, WKUIDelegate {
    

@IBOutlet weak var webViewContainer: UIView!
private var webView: WKWebView?
    

override func viewDidLoad() {
super.viewDidLoad()
        

addWebView()
        

let myURL = URL(string: "https://www.apple.com")
if let myURL = myURL {
let myRequest = URLRequest(url: myURL)
webView?.load(myRequest)
}
}
    

private func addWebView() {
let webConfiguration = WKWebViewConfiguration()
let size = CGSize.init(width: 0.0, height: self.webViewContainer.frame.size.height)
let customFrame = CGRect.init(origin: CGPoint.zero, size: size)
self.webView = WKWebView (frame: customFrame, configuration: webConfiguration)
if let webView = self.webView {
webView.translatesAutoresizingMaskIntoConstraints = false
self.webViewContainer.addSubview(webView)
webView.topAnchor.constraint(equalTo: webViewContainer.topAnchor).isActive = true
webView.rightAnchor.constraint(equalTo: webViewContainer.rightAnchor).isActive = true
webView.leftAnchor.constraint(equalTo: webViewContainer.leftAnchor).isActive = true
webView.bottomAnchor.constraint(equalTo: webViewContainer.bottomAnchor).isActive = true
webView.heightAnchor.constraint(equalTo: webViewContainer.heightAnchor).isActive = true
webView.uiDelegate = self
}
}
}

你可以设置 IPHONEOS_DEPLOYMENT_TARGET > = 11

[部署目标]