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

时间:2017-09-14 14:20:07

标签: ios xcode wkwebview nscoding

有没有人知道如何使用Xcode 9 GM修复此错误?我正在开发一个使用Xcode 8.3制作的应用程序,部署目标适用于iOS 9.3,之前我从未遇到过这个问题。我在这里或Apple论坛上找不到任何信息:(

编辑:当我将WKWebView放入界面构建器时出现此错误,而不是以编程方式使用它。

See picture WKWebView Error

编辑2:嗯,这最终不是一个错误,请参阅下面的Quinn的答案以获得有关此行为的更多信息。感谢他的解释。

11 个答案:

答案 0 :(得分:125)

错误是正确的行为,而不是Xcode 9中的错误。虽然在iOS 8中引入了WKWebView,但-[WKWebView initWithCoder:]中存在一个仅在iOS 11中修复的错误,它总是在运行时崩溃,因此阻止在Interface Builder中配置一个。

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

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

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

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

答案 1 :(得分:76)

这似乎是Xcode 9中的一个错误,也存在于测试版中。如果要通过故事板创建WKWebView,则只会出现构建错误。如果您在相应的ViewController类文件中逐步创建WKWebView,则应该能够在iOS 11以下的iOS版本上构建。 以下是Apple网站上提供的有关如何实现此目标的方法:

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

答案 2 :(得分:46)

如果您想要与其他组件实现自定义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: 0.0, 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)
    }

答案 3 :(得分:22)

如果您从较早的目标迁移到iOS 11.0,但仍然遇到此错误,请使用以下解决方案。

  
      
  1. 转到情节提要(Main.storyboard),单击任何场景。
  2.   
  3. 选择“文件检查器”,它是Xcode的右侧属性窗口。
  4.   
  5. 将“ Builds ”的值更改为“ iOS 11.0及更高版本
  6.   
  7. 编译并构建
  8.   

enter image description here

答案 4 :(得分:12)

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

  1. 在故事板中做任何你想要制作的设计,但留出 WKWebView 的空间,在那个区域拖动&删除视图并将其命名为 webViewContainer 并声明这两个属性,

    @property (weak, nonatomic) IBOutlet UIView *webViewContainer;
    @property(nonatomic, strong)WKWebView *webView;
    
  2. 现在创建并添加webView,如下所示:

    -(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. 现在将这个新创建的webView添加到您的containerView中,如下所示:

    -(void)addWebView:(UIView *)view
    {
          [view addSubview:self.webView];
          [self.webView setTranslatesAutoresizingMaskIntoConstraints:false];
          self.webView.frame = view.frame;
    }
    
  4. 最后,只需加载您的Url,

    -(void)webViewLoadUrl:(NSString *)stringUrl
    {
         NSURL *url = [NSURL URLWithString:stringUrl];
         NSURLRequest *request = [NSURLRequest requestWithURL:url];
         [self.webView loadRequest:request];
    }
    
  5. 感谢您阅读本文。

答案 5 :(得分:2)

//对于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

答案 6 :(得分:1)

WebKit是在 iOS 8 中引入的,但由于发行时出现错误而导致运行时崩溃,如果您使用的是 Xcode 9/10 ,则项目配置支持小于 iOS 11 ,并且如果您尝试使用界面生成器添加WKWebView。 Xcode立即显示编译时错误。

iOS 11.0之前的WKWebView(以前版本中的NSCoding支持已被破坏)

尽管WKWebView是在 iOS 8 中引入的,但是– [WKWebView initWithCoder:]中存在一个错误,该错误仅在 iOS 11 中得到了解决。

enter image description here

解决方法是必须通过代码添加WKWebView(仅当您在iOS 11以下支持时)。听起来真的很奇怪。

另一种解决方案是将用于该选项的Interface Builder文档版本更改为iOS 11及更高版本(如果您是从较早的目标迁移到iOS 11并仍然遇到相同的错误)。

答案 7 :(得分:0)

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
        }
    }
}

答案 8 :(得分:0)

你可以只设置 IPHONEOS_DEPLOYMENT_TARGET >= 11

[Deployment Target]

答案 9 :(得分:-4)

我也遇到了这个问题,但是当我将开发目标设置为11.0时,项目可以运行,但错误仍然存​​在。

答案 10 :(得分:-5)

在iOS11中不推荐使用UIWebView,而WKWebView仅在iOS11中使用 - 这听起来像是Xcode GM中的一个错误。