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


155

有谁知道如何使用Xcode 9 GM修复此错误?我正在开发使用Xcode 8.3制作的应用程序,部署目标是iOS 9.3,并且以前从未遇到过此问题。我在这里或在苹果论坛上找不到任何信息:(

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

见图WKWebView错误

编辑2:好吧,这最终不是错误,请参见下面奎因的答案以获取有关此行为的更多信息。感谢他的解释。


1
请参阅下面的答案。这不是Xcode 9中的bug。在运行之前,iOS的11:没有此版本的错误,你就代替-initWithCoder得到一个崩溃
奎因·泰勒

1
我只是将部署目标更改为11
wei,

Answers:


160

该错误是正确的行为,不是Xcode 9中的错误。尽管WKWebView是在iOS 8中引入的,但其中的一个错误-[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


3
嗨奎因,我相信谁在苹果公司工作的男子:-)我也发现有关你的错误报告:lists.webkit.org/pipermail/webkit-unassigned/2014-September/...谢谢您的回答它真是奇新当我们遇到这样的行为时,像我这样的开发人员。再次感谢。
Mehdi Chennoufi

谢谢!这很有用。
ssowri1'4

2
如果我们也想在ios10中支持怎么办?在我的应用程序中,我还需要支持ios10。我们如何解决此问题?
Kalikanth040494 '18 -10-11

只是好奇为什么苹果要到iOS 11才找出解决办法?
伊曼

96

这似乎是Xcode 9中的错误,并且也存在于beta中。仅当通过情节提要板创建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


5
别忘了super.loadView()
albirrojo7'3

super.loadView()必须在开始时。没有它,什么也没显示。
Makalele,

嗨:),您知道如何将其约束设置在webview我的NavigationBar下方吗?您可以使用此解决方案,但它可以覆盖整个屏幕。
Abed Naseri

@AbedNaseri我认为您不需要施加约束...您可以实例化情节提要,然后实例化self.navigationController?.pushViewController(youVC,animation:true)。
xhinoda

58

如果您还想通过其他组件实现自定义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)
    }

非常感谢,真的很有帮助。这是一种错误认识的苹果
塞巴斯蒂安REMY

1
工作了!在iOS 11和Swift 4.1中进行了测试
Alwin

2
如果您遇到错误[LayoutConstraints] Unable to simultaneously satisfy constraints,请不要忘记这一行webView.translatesAutoresizingMaskIntoConstraints = false。如果将其设置为true,它将webView自动为您创建一整套约束,这将与以编程方式添加的约束冲突。 苹果Docs
mogelbuster '18

51

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

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

在此处输入图片说明


2
@VyachaslavGerchicov:我不了解您,但是在行业中,我们确实有一些较旧的项目需要转换为较新的技术。许多人面临着同样的问题。我已经在答案中提到“如果您已从较旧的目标移走了”。不要只想到一种情况。
甘榜

1
这对我有用,感谢您指出了这个烦人的IB设置。该警告立即消失。实际上,我认为这更实用,应该被接受。同意@Kampai,实际上,由于苹果不断改变其基本框架,我们被迫迁移到新版本的iOS
infinity_coding7

使用iOS 10.x应用在模拟器上运行时执行此操作后崩溃。
拉米斯

@Ramis:我在iOS 10上这样做,我从未遇到应用崩溃的情况,崩溃日志是什么?
甘榜

1
解决此问题的最简单解决方案。谢谢!
杰里·庄

18

我也遇到过同样的问题,但是如果我们编程方式添加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. 最后,像这样加载您的网址,

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

感谢您阅读本文。


3

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

iOS 11.0之前的WKWebView(NSCoding支持在先前版本中已被打破)

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

在此处输入图片说明

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

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


1

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

在此处输入图片说明


0

这应该是对Kampai的回答的评论,但是我没有足够的声誉积分可以发表评论。

除了显式的iOS版本外,“文件检查器”中的“构建为”下拉菜单还包含“ 部署目标(..)”选项。我希望尽可能在一个地方管理版本,并且无论如何都希望更改构建目标。我完全感到困惑,尽管我将常规设置中的相应条目更改为11.0,但仍然说Deployment Target(9.3)

必须重新启动 XCode(11.3.1)才能使所有工作按预期进行,选项“ Deployment Target(11.0)”可用(并且9.3版消失了)。选择之后,一切都按预期进行。


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

-5

UIWebView在iOS11中已弃用,WKWebView仅在iOS11中有效-听起来像Xcode GM中的错误。


是的 如果要在iOS的早期版本上进行部署,我发现的唯一解决方法是以编程方式添加WKWebView。
Mehdi Chennoufi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.