Mehdi Chennoufi
Mehdi Chennoufi

Reputation: 2211

Xcode 9 GM - WKWebView NSCoding support was broken in previous versions

Does anyone know how to fix this error with Xcode 9 GM? I'm working on an app made with Xcode 8.3, the deployment target is for iOS 9.3 and I never had this problem before. I don't find any information here or on Apple forums yet :(

Edit: This error came when I put a WKWebView into interface builder, not if I use it programmatically.

See picture WKWebView Error

Edit 2: Well, it's finally not a bug, see Quinn's answer below to have more information about this behavior. Thanks to him for the explanation.

Upvotes: 177

Views: 67361

Answers (10)

yoAlex5
yoAlex5

Reputation: 34175

You can just set IPHONEOS_DEPLOYMENT_TARGET >= 11

[Deployment Target]

Upvotes: 0

Alessandro Ornano
Alessandro Ornano

Reputation: 35372

If you want to realize a custom UIViewController with other components in addition you can make a "container" through the storyboard called for example 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)
    }

Upvotes: 64

Deviyani Swami
Deviyani Swami

Reputation: 767

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

Upvotes: 0

ShigaSuresh
ShigaSuresh

Reputation: 1768

//For 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)
}
}

// For Objective 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

Upvotes: 3

Mr.Javed Multani
Mr.Javed Multani

Reputation: 13236

WebKit was introduced in iOS 8 but it was released with an error which caused in a runtime crash, If you are using Xcode 9/10, your project configuration support less than iOS 11 and if you are trying to add WKWebView using interface builder. Xcode immediately shows a compile-time error.

WKWebView before iOS 11.0 (NSCoding Support was broken in the previous version)

Although WKWebView was introduced in iOS 8, there was a bug in –[WKWebView initWithCoder:] that was only fixed in iOS 11.

enter image description here

Resolution is you must add WKWebView through code (Only if you are supporting below iOS 11). That actually sounds strange.

Another solution is to change the Interface Builder Document Builds for the option to iOS 11 and later (If you’re migrating from older target to iOS 11 and still getting the same error).

Upvotes: 5

Mehul Patel
Mehul Patel

Reputation: 23053

If you are moved from older target to iOS 11.0 and still you are getting this error, then use below solution.

  1. Go to Storyboard (Main.storyboard), click on any Scene.
  2. Select 'File Inspector' which is the right side property window of Xcode
  3. Change 'Builds for' value to 'iOS 11.0 and Later'
  4. Compile and Build

enter image description here

Upvotes: 63

Quinn Taylor
Quinn Taylor

Reputation: 44769

The error is correct behavior, and not a bug in Xcode 9. Although WKWebView was introduced in iOS 8, there was a bug in -[WKWebView initWithCoder:] that was only fixed in iOS 11, which always crashed at runtime and thus prevented configuring one within Interface Builder.

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

Rather than allow developers to build something in IB that would be broken at runtime, it is a build error. It's an inconvenient limitation since iOS 11 was only recently released, but there's really no other good option.

The workaround for older deployment targets is to continue to add the WKWebView in code, as @fahad-ashraf already described in his answer:

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

Upvotes: 173

Fahad Ashraf
Fahad Ashraf

Reputation: 1138

This seems to be a bug in Xcode 9 and was also present in the betas. You will only get the build error if you are creating a WKWebView through the storyboard. If you progmatically create the WKWebView in the corresponding ViewController class file, you should be able to build on iOS versions below iOS 11. Here is the approach given on Apple's website for how to accomplish this:

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

You should then be able to implement WKWebView functionality as you normally would.

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

Upvotes: 100

Najam
Najam

Reputation: 1159

I have faced the same issue but it can be tackle if we add WKWebView programmatically.

  1. Do whatever design you want to make in storyboard but leave the room for WKWebView, in that area drag & drop a view and name it as webViewContainer and declare these two properties,

    @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 function is declared as,

    -(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.

Upvotes: 18

pawel221
pawel221

Reputation: 1007

UIWebView is deprecated in iOS11 and WKWebView works only in iOS11 - this sounds like a bug in Xcode GM.

Upvotes: -5

Related Questions