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.