Xcode 9 GM - поддержка WSCWebView NSCoding была нарушена в предыдущих версиях


155

Кто-нибудь знает, как исправить эту ошибку с Xcode 9 GM? Я работаю над приложением, созданным с помощью Xcode 8.3, цель развертывания - для iOS 9.3, и у меня никогда не было этой проблемы раньше. Я не нахожу никакой информации здесь или на форумах Apple, пока :(

Изменить: эта ошибка возникла, когда я поместил WKWebView в конструктор интерфейса, а не, если я использую его программно.

Смотрите картинку WKWebView Ошибка

Изменить 2: Ну, это, наконец, не ошибка, см. Ответ Куинн ниже, чтобы получить больше информации об этом поведении. Спасибо ему за объяснение.


1
Смотрите мой ответ ниже. Это не ошибка в Xcode 9; без этой ошибки сборки вместо этого вы получите сбой в -initWithCoder: во время выполнения до iOS 11.
Quinn Taylor

1
Я просто изменил свою цель развертывания на 11
Вэй

Ответы:


160

Ошибка - правильное поведение, а не ошибка в Xcode 9. Хотя WKWebView был представлен в iOS 8, была ошибка, -[WKWebView initWithCoder:]которая была исправлена ​​только в iOS 11, которая всегда приводила к сбою во время выполнения и, таким образом, препятствовала его настройке в Интерфейсном Разработчике.

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

Вместо того, чтобы позволять разработчикам создавать что-то в IB, которое будет сломано во время выполнения, это ошибка сборки. Это неудобное ограничение, поскольку iOS 11 была выпущена совсем недавно, но другого хорошего варианта действительно нет.

Обходной путь для более старых целей развертывания состоит в том, чтобы продолжать добавлять WKWebView в код, как @fahad-ashraf уже описал в своем ответе:

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


3
Привет, Куинн, я думаю, что человек, который работает в Apple :-) Я также нашел твой отчет об ошибке об этом: lists.webkit.org/pipermail/webkit-unassigned/2014-September/… Спасибо за твой ответ, это действительно удивительно для новых разработчики любят меня, когда мы сталкиваемся с таким поведением. Еще раз спасибо.
Мехди Ченнуфи

Спасибо! Это было полезно.
ssowri1

2
Что, если мы хотим поддержать и в ios10? В моем приложении мне также нужно поддерживать ios 10. Как мы можем решить эту проблему?
Kalikanth040494

просто любопытно, почему Apple потребовалось до iOS 11, чтобы найти решение?
Эман

96

Это, кажется, ошибка в Xcode 9 и также присутствовала в бета-версиях. Вы получите только ошибку сборки, если создаете WKWebView через раскадровку. Если вы постепенно создадите WKWebView в соответствующем файле класса ViewController, вы сможете использовать версии iOS ниже iOS 11. Вот подход, предложенный на веб-сайте 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

super.loadView()должно быть в начале. Без этого ничего не показывает.
Makalele

Привет :), вы знаете, как я могу установить ограничения этого webviewниже моего NavigationBar? Это ваше решение работает, но оно охватывает весь экран.
Абед Насери

@AbedNaseri Я думаю, вам не нужно устанавливать ограничения ... вы можете создать экземпляр раскадровки, а затем self.navigationController? .PushViewController (youVC, animated: 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)
    }

Большое спасибо, это действительно помогает. Это ошибка, которую знает Apple
Себастьян

1
Работал! протестировано в iOS 11 и Swift 4.1
Alwin

2
Если вы получаете ошибку [LayoutConstraints] Unable to simultaneously satisfy constraints, не забудьте строку webView.translatesAutoresizingMaskIntoConstraints = false. Если вы оставите для него значение true, оно автоматически создаст для вас целый набор ограничений, webViewкоторые будут конфликтовать с ограничениями, которые вы добавляете программно. Apple Docs .
Могельбастер

51

Если вы перешли с более старой цели на iOS 11.0 и по-прежнему получаете эту ошибку, воспользуйтесь приведенным ниже решением.

  1. Перейдите в раскадровку (Main.storyboard), нажмите на любую сцену.
  2. Выберите «File Inspector», который является правым окном свойств Xcode
  3. Измените значение « Builds for » на « iOS 11.0 и более поздние версии »
  4. Компилировать и строить

введите описание изображения здесь


2
@VyachaslavGerchicov: Я не знаю о вас, но в отрасли у нас есть такие старые проекты, которые необходимо преобразовать в новые технологии. Многие сталкиваются с одной и той же проблемой. Я уже упоминал в ответе, что «если вы перешли от более старой цели». Не думай только об одном случае.
Кампай

1
Это работает для меня, спасибо за указание на эту надоедливую настройку IB. Предупреждение исчезло сразу. Собственно, я считаю это более практичным и должен быть принят ответ. Согласитесь с @Kampai, на самом деле мы вынуждены перейти на новую версию iOS, поскольку Apple постоянно меняет свои фундаментальные рамки
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. Теперь добавьте этот вновь созданный веб-вид в свой контейнер-вид, например так:

    -(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];
    }

Спасибо, что прочитали это.


3

WebKit был представлен в iOS 8, но был выпущен с ошибкой, которая вызвала сбой во время выполнения. Если вы используете Xcode 9/10 , конфигурация вашего проекта поддерживает меньше, чем iOS 11, и если вы пытаетесь добавить WKWebView с помощью построителя интерфейса. Xcode сразу показывает ошибку во время компиляции.

WKWebView до iOS 11.0 (поддержка NSCoding была прервана в предыдущей версии)

Хотя WKWebView был представлен в iOS 8 , в [WKWebView initWithCoder:] была ошибка, исправленная только в iOS 11 .

введите описание изображения здесь

Решение - вы должны добавить WKWebView через код (только если вы поддерживаете ниже iOS 11). Это на самом деле звучит странно.

Другое решение - изменить сборки документов Interface Builder для этой опции на iOS 11 и более поздние версии (если вы переходите с более старой цели на iOS 11 и по-прежнему получаете ту же ошибку).


1

// Для Свифта

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

Это должен быть комментарий к ответу Кампая, но у меня недостаточно репутации, чтобы комментировать.

Помимо явных версий iOS, раскрывающийся список «Сборки для» в «Инспекторе файлов» также содержит параметр « Цель развертывания (..)» . Я предпочитаю управлять версиями в одном месте, если это возможно, и все равно хотел изменить цель сборки. Я был полностью сбит с толку, он по-прежнему говорил Deployment Target (9.3), хотя я изменил соответствующую запись в общих настройках на 11.0 .

Перезапуск 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 программным способом.
Мехди Ченнуфи
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.