Dukungan Xcode 9 GM - WKWebView NSCoding rusak di versi sebelumnya


155

Adakah yang tahu cara memperbaiki kesalahan ini dengan Xcode 9 GM? Saya sedang mengerjakan aplikasi yang dibuat dengan Xcode 8.3, target penyebaran adalah untuk iOS 9.3 dan saya tidak pernah mengalami masalah ini sebelumnya. Saya belum menemukan informasi di sini atau di forum Apple :(

Sunting: Kesalahan ini terjadi ketika saya memasukkan WKWebView ke pembuat antarmuka, bukan jika saya menggunakannya secara terprogram.

Lihat gambar Kesalahan WKWebView

Sunting 2: Ya, itu akhirnya bukan bug, lihat jawaban Quinn di bawah untuk mendapatkan informasi lebih lanjut tentang perilaku ini. Terima kasih padanya untuk penjelasannya.


1
Lihat jawaban saya di bawah ini. Ini bukan bug di Xcode 9; tanpa kesalahan build ini, Anda malah akan mendapatkan crash di -initWithCoder: saat runtime sebelum iOS 11.
Quinn Taylor

1
Saya baru saja mengubah target penempatan saya menjadi 11
wei

Jawaban:


160

Kesalahannya adalah perilaku yang benar, dan bukan bug di Xcode 9. Meskipun WKWebView diperkenalkan di iOS 8, ada bug di dalamnya -[WKWebView initWithCoder:]yang hanya diperbaiki di iOS 11, yang selalu macet saat runtime dan karenanya mencegah konfigurasi satu di dalam Interface Builder.

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

Alih-alih mengizinkan pengembang untuk membangun sesuatu di IB yang akan rusak saat runtime, itu adalah kesalahan build. Ini adalah batasan yang tidak nyaman karena iOS 11 baru saja dirilis, tetapi sebenarnya tidak ada pilihan lain yang bagus.

Solusi untuk target penempatan yang lebih lama adalah untuk terus menambahkan kode WKWebView, karena @ fahad-ashraf sudah dijelaskan dalam jawabannya:

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


3
Hai Quinn, saya percaya pria yang bekerja di Apple :-) Saya juga menemukan laporan bug Anda tentang itu: lists.webkit.org/pipermail/webkit-unassigned/2014-September/... Terima kasih atas jawaban Anda, benar-benar mengejutkan untuk yang baru pengembang menyukai saya ketika kami menghadapi perilaku seperti itu. Terima kasih lagi.
Mehdi Chennoufi

Terima kasih! Itu berguna.
ssowri1

2
bagaimana jika kita ingin mendukung di ios10 juga? di aplikasi saya, saya perlu mendukung ios 10 juga. Bagaimana kita bisa menyelesaikan masalah ini?
Kalikanth040494

hanya ingin tahu mengapa perlu Apple sampai iOS 11 untuk mencari tahu cara memperbaikinya?
Eman

96

Ini sepertinya merupakan bug di Xcode 9 dan juga ada di betas. Anda hanya akan mendapatkan galat build jika Anda membuat WKWebView melalui storyboard. Jika Anda secara progmatic membuat WKWebView dalam file kelas ViewController yang sesuai, Anda harus dapat membangun versi iOS di bawah iOS 11. Berikut adalah pendekatan yang diberikan di situs web Apple untuk bagaimana menyelesaikannya:

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

Anda kemudian dapat mengimplementasikan fungsionalitas WKWebView seperti biasa.

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


5
jangan lupasuper.loadView()
albirrojo7

super.loadView()harus di awal. Tanpa itu, tidak ada yang terlihat.
Makalele

hai :), tahukah Anda bagaimana saya dapat mengatur kendala ini di webviewbawah NavigationBar saya? Solusi Anda ini berfungsi tetapi mencakup seluruh layar.
Abed Naseri

@AbedNaseri saya pikir Anda tidak perlu menempatkan kendala ... Anda dapat instantiate storyboard dan kemudian self.navigationController? .PushViewController (youVC, animated: true).
xhinoda

58

Jika Anda ingin mewujudkan kebiasaanUIViewController dengan komponen lain selain itu Anda dapat membuat "wadah" melalui storyboard yang disebut misalnya 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)
    }

Terima kasih banyak, ini sangat membantu. Ini adalah bug yang diketahui oleh Apple
SĂ©bastien REMY

1
Bekerja! diuji di iOS 11 dan swift 4.1
Alwin

2
Jika Anda mendapatkan kesalahan [LayoutConstraints] Unable to simultaneously satisfy constraints, jangan lupa garisnya webView.translatesAutoresizingMaskIntoConstraints = false. Jika Anda membiarkannya menjadi true, itu akan membuat seluruh rangkaian kendala untuk Anda webViewsecara otomatis yang akan bertentangan dengan kendala yang Anda tambahkan secara programatis. Apple Documents .
mogelbuster

51

Jika Anda dipindahkan dari target lama ke iOS 11.0 dan masih Anda mendapatkan kesalahan ini, maka gunakan solusi di bawah ini.

  1. Pergi ke Storyboard (Main.storyboard), klik pada Scene apa saja.
  2. Pilih 'File Inspector' yang merupakan jendela properti sisi kanan Xcode
  3. Ubah nilai ' Builds for ' ke ' iOS 11.0 and Later '
  4. Kompilasi dan Bangun

masukkan deskripsi gambar di sini


2
@VyachaslavGerchicov: Saya tidak tahu tentang Anda, tetapi di industri ini, kami memiliki proyek yang lebih tua yang perlu dikonversi ke teknologi yang lebih baru. Begitu banyak yang menghadapi masalah yang sama. Saya sudah menyebutkan dalam jawaban bahwa "jika Anda dipindahkan dari target yang lebih tua". Jangan hanya memikirkan satu kasus.
Kampai

1
Ini berfungsi untuk saya, terima kasih telah menunjukkan pengaturan IB yang mengganggu ini. Peringatan itu segera hilang. Sebenarnya, menurut saya ini lebih praktis dan harus diterima jawabannya. Setuju dengan @Kampai, sebenarnya, kita dipaksa untuk pindah ke versi baru iOS, karena Apple terus mengubah kerangka dasar mereka
infinity_coding7

Setelah melakukannya ketika berjalan di simulator dengan aplikasi iOS 10.x crash.
Ramis

@Ramis: Saya melakukannya untuk iOS 10, saya tidak pernah mengalami crash aplikasi, apa itu crash log?
Kampai

1
Solusi paling sederhana untuk memperbaiki masalah ini. Terima kasih!
Jerry Chong

18

Saya telah menghadapi masalah yang sama tetapi bisa diatasi jika kita menambahkan WKWebView secara terprogram.

  1. Lakukan desain apa pun yang ingin Anda buat di storyboard tetapi tinggalkan ruangan untuk WKWebView , di area itu seret & letakkan tampilan dan beri nama sebagai webViewContainer dan nyatakan dua properti ini,

    @property (weak, nonatomic) IBOutlet UIView *webViewContainer;
    @property(nonatomic, strong)WKWebView *webView;
  2. Sekarang buat dan tambahkan webView seperti ini:

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

    Fungsi createWebView dinyatakan sebagai,

    -(WKWebView *)createWebView
    {
         WKWebViewConfiguration *configuration = 
                   [[WKWebViewConfiguration alloc] init];
         return [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
    }
  3. Sekarang tambahkan webView yang baru dibuat ini ke containerView Anda, seperti ini:

    -(void)addWebView:(UIView *)view
    {
          [view addSubview:self.webView];
          [self.webView setTranslatesAutoresizingMaskIntoConstraints:false];
          self.webView.frame = view.frame;
    }
  4. Akhirnya, muat Url Anda seperti ini,

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

Terima kasih sudah membaca ini.


3

WebKit diperkenalkan di iOS 8 tetapi dirilis dengan kesalahan yang menyebabkan crash runtime, Jika Anda menggunakan Xcode 9/10 , konfigurasi proyek Anda mendukung kurang dari iOS 11 dan jika Anda mencoba menambahkan WKWebView menggunakan pembangun antarmuka. Xcode segera menunjukkan kesalahan waktu kompilasi.

WKWebView sebelum iOS 11.0 (Dukungan NSCoding rusak di versi sebelumnya)

Meskipun WKWebView diperkenalkan di iOS 8 , ada bug di - [WKWebView initWithCoder:] yang hanya diperbaiki di iOS 11 .

masukkan deskripsi gambar di sini

Penyelesaiannya adalah Anda harus menambahkan kode WKWebView melalui (Hanya jika Anda mendukung di bawah iOS 11). Itu sebenarnya terdengar aneh.

Solusi lain adalah mengubah Builder Document Builds untuk opsi ke iOS 11 dan yang lebih baru (Jika Anda bermigrasi dari target lama ke iOS 11 dan masih mendapatkan kesalahan yang sama).


1

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

// Untuk Tujuan 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

masukkan deskripsi gambar di sini


0

Ini seharusnya menjadi komentar atas jawaban Kampai, tetapi saya tidak memiliki poin reputasi yang cukup untuk berkomentar.

Selain versi iOS eksplisit, dropdown 'Builds for' di 'File Inspector' juga berisi opsi Deployment Target (..) . Saya lebih suka mengelola versi di satu tempat jika memungkinkan dan ingin mengubah target pembangunan. Saya sepenuhnya bingung itu masih mengatakan Deployment Target (9.3) meskipun saya mengubah entri yang sesuai dalam pengaturan umum ke 11.0 .

Restart XCode (11.3.1) diperlukan untuk membuat semuanya berfungsi seperti yang diharapkan, opsi 'Deployment Target (11.0)' tersedia (dan 9.3 hilang). Setelah pemilihan semuanya bekerja seperti yang diharapkan.


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 sudah usang di iOS11 dan WKWebView hanya berfungsi di iOS11 - ini terdengar seperti bug di Xcode GM.


Ya. Satu-satunya solusi yang saya temukan jika Anda ingin menggunakan iOS versi sebelumnya adalah menambahkan WKWebView Anda secara terprogram.
Mehdi Chennoufi
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.