Xcode 9 GM - підтримка WKWebView NSCoding була зламана в попередніх версіях


155

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

Редагувати: Ця помилка виникла, коли я помістив WKWebView в конструктор інтерфейсів, а не якщо я його програмно використовую.

Дивіться зображення WKWebView Помилка

Редагування 2: Ну, нарешті, це не помилка, див. Відповідь Квін нижче, щоб отримати більше інформації про цю поведінку. Дякую йому за пояснення.


1
Дивіться мою відповідь нижче. Це не помилка в Xcode 9; без цієї помилки побудови ви б замість цього отримали збій у -initWithCoder: під час виконання до iOS 11.
— Квінн Тейлор

1
Я просто міняю свою ціль розгортання на 11
— ве

Відповіді:


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
Привіт Куінн, я вважаю, що чоловік, який працює в Apple :-) Я також знайшов ваш звіт про помилку щодо цього: list.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()має бути на початку. Без нього нічого не показує.
— Макалеле

привіт :), ти знаєш, як я можу встановити обмеження цього webviewнижче, ніж мій навігаційний бар? Це ваше рішення працює, але воно охоплює весь екран.
— Абед Насері

@AbedNaseri Я думаю, вам не потрібно ставити обмеження ... ви можете створити розгорнуту таблицю, а потім self.navigationController? .PushViewController (youVC, анімований: правда).
— 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
— Sébastien REMY

1
Працювали! перевірено на iOS 11 та стрімкому 4.1
— Альвін

2
Якщо ви отримуєте помилку [LayoutConstraints] Unable to simultaneously satisfy constraints, не забувайте рядок webView.translatesAutoresizingMaskIntoConstraints = false. Якщо залишити його встановленим як істинне, воно створить цілий набір обмежень для Вашого webViewавтоматично, які будуть суперечити обмеженням, які Ви додаєте програмно. Apple Docs .
— mogelbuster

51

Якщо ви переміщені зі старої цілі на iOS 11.0 і все ще отримуєте цю помилку, тоді використовуйте рішення нижче.

  1. Перейдіть до «Розгортки» (Main.storyboard), клацніть на будь-якій сцені.
  2. Виберіть "Інспектор файлів", що є правою частиною вікна властивостей Xcode
  3. Змініть значення " Збірка для " на " 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). Це насправді звучить дивно.

Іншим рішенням є зміна збірок документів для збирання інтерфейсів на параметр на 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)
}
}

// Для мети С

#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, у спадному меню "Інспектор файлів" вибудовується для "IOS" також міститься опція " Ціль розгортання" (..) . Я вважаю за краще керувати версіями в одному місці, якщо це можливо, і хотів би змінити ціль збірки. Я був повністю збентежений, він все ще говорив про ціль розгортання (9.3), хоча я змінив відповідний запис у загальних налаштуваннях на 11.0 .

Перезапуск XCode (11.3.1) був необхідний, щоб все працювало так, як очікувалося, була доступна опція "Ціль розгортання (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.