Xcode 9 GM - Il supporto per la codifica NS di WKWebView era interrotto nelle versioni precedenti


155

Qualcuno sa come correggere questo errore con Xcode 9 GM? Sto lavorando su un'app realizzata con Xcode 8.3, il target di distribuzione è per iOS 9.3 e non ho mai avuto questo problema prima. Non trovo ancora alcuna informazione qui o sui forum Apple :(

Modifica: questo errore è arrivato quando ho inserito un WKWebView nel generatore di interfacce, non se lo uso a livello di codice.

Vedi foto Errore WWWebView

Modifica 2: Beh, finalmente non è un bug, vedi la risposta di Quinn di seguito per avere maggiori informazioni su questo comportamento. Grazie a lui per la spiegazione.


1
Vedi la mia risposta qui sotto. Questo non è un bug in Xcode 9; senza questo errore di build, si otterrebbe invece un arresto anomalo in -initWithCoder: in fase di esecuzione prima di iOS 11.
Quinn Taylor

1
Ho appena cambiato il mio obiettivo di implementazione in 11
wei

Risposte:


160

L'errore è un comportamento corretto e non un bug in Xcode 9. Sebbene WKWebView sia stato introdotto in iOS 8, c'era un bug -[WKWebView initWithCoder:]che veniva risolto solo in iOS 11, che si bloccava sempre in fase di esecuzione e impediva quindi di configurarne uno in Interface Builder.

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

Invece di consentire agli sviluppatori di creare qualcosa in IB che si romperebbe durante l'esecuzione, si tratta di un errore di compilazione. È una limitazione scomoda poiché iOS 11 è stato rilasciato solo di recente, ma in realtà non c'è altra buona opzione.

La soluzione alternativa per gli obiettivi di distribuzione meno recenti è quella di continuare ad aggiungere WKWebView nel codice, come già descritto da @ fahad-ashraf nella sua risposta:

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


3
Ciao Quinn, credo che l'uomo che lavora in Apple :-) Ho trovato anche la tua segnalazione di bug al riguardo: lists.webkit.org/pipermail/webkit-unassigned/2014-September/… Grazie per la tua risposta è davvero sorprendente per i nuovi agli sviluppatori come me quando incontriamo un comportamento del genere. Grazie ancora.
Mehdi Chennoufi,

Grazie! È stato utile.
ssowri1,

2
cosa succede se vogliamo supportare anche in ios10 ?. nella mia app devo supportare anche iOS 10. Come possiamo risolvere questo problema?
Kalikanth040494,

solo curioso perché ci è voluto Apple fino a iOS 11 per capire una soluzione?
Eman,

96

Questo sembra essere un bug in Xcode 9 ed era presente anche nei beta. Riceverai l'errore di compilazione solo se stai creando un WKWebView tramite lo storyboard. Se crei WKWebView in modo programmatico nel file di classe ViewController corrispondente, dovresti essere in grado di sviluppare versioni iOS inferiori a iOS 11. Ecco l'approccio fornito sul sito Web di Apple per ottenere questo risultato:

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

Dovresti quindi essere in grado di implementare la funzionalità di WKWebView come faresti normalmente.

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


5
non dimenticaresuper.loadView()
albirrojo7

super.loadView()deve essere all'inizio. Senza di essa, nulla mostra.
Makalele,

ciao :), sai come posso impostare i vincoli di questo webviewsotto il mio NavigationBar? Questa soluzione funziona ma copre l'intero schermo.
Abed Naseri

@AbedNaseri penso che non sia necessario mettere vincoli ... puoi istanziare lo storyboard e quindi self.navigationController? .PushViewController (youVC, animato: vero).
xhinoda,

58

Se vuoi realizzare un'abitudine ancheUIViewController con altri componenti, puoi creare un "contenitore" attraverso lo storyboard chiamato ad esempio 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)
    }

Grazie mille, è davvero di aiuto. È un bug conosciuto da Apple
Sébastien REMY il

1
Lavorato! testato su iOS 11 e rapido 4.1
Alwin,

2
Se ricevi l'errore [LayoutConstraints] Unable to simultaneously satisfy constraints, non dimenticare la riga webView.translatesAutoresizingMaskIntoConstraints = false. Se lo lasci impostato su true, creerà automaticamente un intero insieme di vincoli webViewche entreranno in conflitto con i vincoli aggiunti a livello di programmazione. Documenti Apple .
mogelbuster,

51

Se vieni spostato dal target precedente a iOS 11.0 e stai ancora riscontrando questo errore, utilizza la soluzione di seguito.

  1. Vai su Storyboard (Main.storyboard), fai clic su qualsiasi scena.
  2. Seleziona "File Inspector" che è la finestra delle proprietà sul lato destro di Xcode
  3. Modifica il valore " Build per " in " iOS 11.0 e versioni successive "
  4. Compila e costruisci

inserisci qui la descrizione dell'immagine


2
@VyachaslavGerchicov: Non ti conosco, ma nel settore abbiamo progetti così vecchi che devono essere convertiti in tecnologia più recente. Così tanti affrontano lo stesso problema. Ho già menzionato nella risposta che "se vieni spostato dal bersaglio più vecchio". Non pensare a un solo caso.
Kampai,

1
Questo funziona per me grazie per aver indicato questa fastidiosa configurazione IB. L'avvertimento è sparito immediatamente. In realtà, penso che questo sia più pratico e dovrebbe essere accettata la risposta. Concordo con @Kampai, in realtà, siamo costretti a passare alla nuova versione di iOS, poiché la Apple continua a cambiare i suoi framework fondamentali
infinity_coding7

Dopo averlo fatto durante l'esecuzione sul simulatore con l'app iOS 10.x si arresta in modo anomalo.
Ramis,

@Ramis: lo stavo facendo per iOS 10, non ho mai avuto un crash dell'applicazione, qual era il registro degli arresti anomali?
Kampai,

1
La soluzione più semplice per risolvere questo problema. Grazie!
Jerry Chong,

18

Ho affrontato lo stesso problema, ma può essere affrontato se aggiungiamo WKWebView a livello di codice .

  1. Fai qualsiasi progetto tu voglia realizzare nello storyboard ma lascia spazio a WKWebView , trascina in quella zona una vista e chiamala come webViewContainer e dichiara queste due proprietà,

    @property (weak, nonatomic) IBOutlet UIView *webViewContainer;
    @property(nonatomic, strong)WKWebView *webView;
  2. Ora crea e aggiungi webView in questo modo:

    -(instancetype)initWithCoder:(NSCoder *)aDecoder
    {
        self.webView = [self createWebView];
        self = [super initWithCoder:aDecoder];
        return self;
    }

    La funzione createWebView è dichiarata come,

    -(WKWebView *)createWebView
    {
         WKWebViewConfiguration *configuration = 
                   [[WKWebViewConfiguration alloc] init];
         return [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
    }
  3. Ora aggiungi questa webView appena creata al tuo containerView, in questo modo:

    -(void)addWebView:(UIView *)view
    {
          [view addSubview:self.webView];
          [self.webView setTranslatesAutoresizingMaskIntoConstraints:false];
          self.webView.frame = view.frame;
    }
  4. Infine, carica l'URL in questo modo,

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

Grazie per aver letto questo.


3

WebKit è stato introdotto in iOS 8 ma è stato rilasciato con un errore che ha causato un arresto anomalo del runtime. Se si utilizza Xcode 9/10 , la configurazione del progetto supporta meno di iOS 11 e se si sta tentando di aggiungere WKWebView utilizzando l'interfaccia builder. Xcode mostra immediatamente un errore in fase di compilazione.

WKWebView prima di iOS 11.0 (il supporto per NSCoding era rotto nella versione precedente)

Sebbene WKWebView sia stato introdotto in iOS 8 , c'era un bug in - [WKWebView initWithCoder:] che era stato corretto solo in iOS 11 .

inserisci qui la descrizione dell'immagine

La risoluzione è che devi aggiungere WKWebView tramite il codice (solo se stai supportando sotto iOS 11). Sembra davvero strano.

Un'altra soluzione è quella di modificare le build del documento di Interface Builder per l'opzione su iOS 11 e versioni successive (se stai migrando da una destinazione precedente a iOS 11 e stai ancora riscontrando lo stesso errore).


1

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

// Per l'obiettivo 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

inserisci qui la descrizione dell'immagine


0

Questo dovrebbe essere un commento sulla risposta di Kampai, ma non ho abbastanza punti reputazione per commentare.

Oltre alle versioni esplicite di iOS, il menu a discesa "Builds for" in "File Inspector" contiene anche l' opzione Deployment Target (..) . Preferisco gestire le versioni in un unico posto, se possibile, e volevo cambiare comunque l'obiettivo di compilazione. Ero completamente confuso, diceva ancora Deployment Target (9.3) anche se ho cambiato la voce corrispondente nelle impostazioni generali in 11.0 .

Il riavvio di XCode (11.3.1) era necessario per far funzionare tutto come previsto, l'opzione 'Destinazione di distribuzione (11.0)' era disponibile (e 9.3 era sparita). Dopo la selezione tutto ha funzionato come previsto.


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 è obsoleto in iOS11 e WKWebView funziona solo in iOS11 - questo sembra un bug in Xcode GM.


Sì. L'unica soluzione alternativa che ho riscontrato se si desidera distribuire su una versione precedente di iOS è aggiungere WKWebView a livello di codice.
Mehdi Chennoufi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.