Xcode 9 GM - Hỗ trợ NKWoding của WKWebView đã bị hỏng trong các phiên bản trước


155

Có ai biết cách khắc phục lỗi này với Xcode 9 GM không? Tôi đang làm việc trên một ứng dụng được tạo bằng Xcode 8.3, mục tiêu triển khai là dành cho iOS 9.3 và tôi chưa bao giờ gặp sự cố này trước đây. Tôi chưa tìm thấy bất kỳ thông tin nào ở đây hoặc trên các diễn đàn của Apple :(

Chỉnh sửa: Lỗi này xuất hiện khi tôi đặt WKWebView vào trình tạo giao diện, chứ không phải nếu tôi sử dụng nó theo chương trình.

Xem hình ảnh Lỗi WKWebView

Chỉnh sửa 2: Chà, cuối cùng không phải là lỗi, hãy xem câu trả lời của Quinn bên dưới để có thêm thông tin về hành vi này. Cảm ơn anh đã giải thích.


1
Xem câu trả lời của tôi dưới đây. Đây không phải là một lỗi trong Xcode 9; không có lỗi xây dựng này, thay vào đó, bạn sẽ gặp sự cố trong -initWithCoder: tại thời gian chạy trước iOS 11.
Quinn Taylor

1
Tôi chỉ cần thay đổi mục tiêu triển khai của tôi đến 11
wei

Câu trả lời:


160

Lỗi là hành vi chính xác và không phải là lỗi trong Xcode 9. Mặc dù WKWebView đã được giới thiệu trong iOS 8, nhưng có một lỗi -[WKWebView initWithCoder:]chỉ được sửa trong iOS 11, luôn bị lỗi khi chạy và do đó không thể cấu hình một lỗi trong Trình tạo giao diện.

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

Thay vì cho phép các nhà phát triển xây dựng một cái gì đó trong IB sẽ bị hỏng trong thời gian chạy, đó là một lỗi xây dựng. Đó là một hạn chế bất tiện vì iOS 11 chỉ mới được phát hành gần đây, nhưng thực sự không có lựa chọn tốt nào khác.

Cách giải quyết cho các mục tiêu triển khai cũ hơn là tiếp tục thêm WKWebView trong mã, vì @ fahad-ashraf đã được mô tả trong câu trả lời của mình:

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


3
Xin chào Quinn, tôi tin rằng người đàn ông làm việc tại Apple :-) Tôi cũng đã tìm thấy báo cáo lỗi của bạn về điều đó: List.webkit.org/pipermail/webkit-unassign/2014-September/ trộm Cảm ơn bạn vì câu trả lời của bạn thật sự đáng ngạc nhiên vì mới các nhà phát triển như tôi khi chúng ta gặp phải một hành vi như vậy. Cảm ơn một lần nữa.
Mehdi Chennoufi

Cảm ơn bạn! Nó rất hữu ích.
ssowri1

2
Điều gì nếu chúng tôi muốn hỗ trợ trong ios10? trong ứng dụng của tôi, tôi cũng cần hỗ trợ ios 10. Làm thế nào chúng ta có thể giải quyết vấn đề này?
Kalikanth040494

chỉ tò mò tại sao Apple phải mất đến iOS 11 để tìm ra cách khắc phục?
Eman

96

Đây dường như là một lỗi trong Xcode 9 và cũng có mặt trong betas. Bạn sẽ chỉ nhận được lỗi xây dựng nếu bạn đang tạo WKWebView thông qua bảng phân cảnh. Nếu bạn chủ động tạo WKWebView trong tệp lớp ViewContoder tương ứng, bạn sẽ có thể xây dựng trên các phiên bản iOS bên dưới iOS 11. Đây là cách tiếp cận được đưa ra trên trang web của Apple để biết cách thực hiện điều này:

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

Sau đó, bạn sẽ có thể triển khai chức năng WKWebView như bình thường.

Nguồn: https://developer.apple.com/documentation/webkit/wkwebview


5
đừng quênsuper.loadView()
albirrojo7

super.loadView()phải ở đầu Không có nó, không có gì cho thấy.
Makalele

hi :), bạn có biết làm thế nào tôi có thể đặt các ràng buộc này webviewxuống bên dưới NavigationBar của mình không? Giải pháp này của bạn hoạt động nhưng nó bao phủ toàn bộ màn hình.
Abed Naseri

@AbedNaseri Tôi nghĩ rằng bạn không cần phải đặt các ràng buộc ... bạn có thể khởi tạo bảng phân cảnh và sau đó self.navestionControll? .PushViewControll (youVC, hoạt hình: true).
xhinoda

58

Nếu bạn muốn nhận ra một tùy chỉnhUIViewController với các thành phần khác, bạn có thể tạo một "thùng chứa" thông qua bảng phân cảnh được gọi là ví dụ 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)
    }

Cảm ơn bạn rất nhiều, nó thực sự giúp đỡ. Đó là một lỗi được biết bởi Apple
Sébastien REMY

1
Đã làm việc! đã thử nghiệm trong iOS 11 và swift 4.1
Alwin

2
Nếu bạn đang gặp lỗi [LayoutConstraints] Unable to simultaneously satisfy constraints, đừng quên dòng webView.translatesAutoresizingMaskIntoConstraints = false. Nếu bạn đặt nó thành đúng, nó sẽ tự động tạo ra một tập hợp các ràng buộc webView, điều này sẽ xung đột với các ràng buộc bạn thêm theo chương trình. Tài liệu Apple .
mogelbuster

51

Nếu bạn được chuyển từ mục tiêu cũ sang iOS 11.0 và bạn vẫn gặp phải lỗi này, thì hãy sử dụng giải pháp bên dưới.

  1. Chuyển đến Storyboard (Main.storyboard), nhấp vào bất kỳ Cảnh nào.
  2. Chọn 'Trình kiểm tra tệp' là cửa sổ thuộc tính bên phải của Xcode
  3. Thay đổi giá trị 'Bản dựng cho ' thành ' iOS 11.0 trở lên '
  4. Biên dịch và xây dựng

nhập mô tả hình ảnh ở đây


2
@VyachaslavGerchicov: Tôi không biết về bạn, nhưng trong ngành, chúng tôi có những dự án cũ hơn cần được chuyển đổi sang công nghệ mới hơn. Vì vậy, nhiều người phải đối mặt với cùng một vấn đề. Tôi đã đề cập trong câu trả lời rằng "nếu bạn được chuyển từ mục tiêu cũ hơn". Đừng nghĩ chỉ một trường hợp.
Kampai

1
Điều này làm việc cho tôi cảm ơn vì đã chỉ ra thiết lập IB gây phiền nhiễu này. Cảnh báo đã biến mất ngay lập tức. Trên thực tế, tôi nghĩ rằng điều này thực tế hơn và nên được chấp nhận câu trả lời. Đồng ý với @Kampai, thực tế, chúng tôi buộc phải chuyển sang phiên bản iOS mới, vì Apple liên tục thay đổi các khung cơ bản của họ
infinity_coding7

Sau khi thực hiện khi chạy trên trình giả lập với ứng dụng iOS 10.x gặp sự cố.
Ramis

@Ramis: Tôi đang làm điều đó cho iOS 10, tôi chưa bao giờ gặp sự cố ứng dụng, nhật ký sự cố là gì?
Kampai

1
Giải pháp đơn giản nhất để khắc phục vấn đề này. Cảm ơn!
Jerry Chong

18

Tôi đã đối mặt với cùng một vấn đề nhưng nó có thể được giải quyết nếu chúng ta thêm WKWebView theo chương trình.

  1. Thực hiện bất kỳ thiết kế nào bạn muốn thực hiện trong bảng phân cảnh nhưng để lại chỗ cho WKWebView , trong khu vực đó kéo và thả chế độ xem và đặt tên là webViewContainer và khai báo hai thuộc tính này,

    @property (weak, nonatomic) IBOutlet UIView *webViewContainer;
    @property(nonatomic, strong)WKWebView *webView;
  2. Bây giờ tạo và thêm webView như thế này:

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

    Hàm createdWebView được khai báo là,

    -(WKWebView *)createWebView
    {
         WKWebViewConfiguration *configuration = 
                   [[WKWebViewConfiguration alloc] init];
         return [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
    }
  3. Bây giờ hãy thêm webView mới được tạo này vào containerView của bạn, như thế này ,:

    -(void)addWebView:(UIView *)view
    {
          [view addSubview:self.webView];
          [self.webView setTranslatesAutoresizingMaskIntoConstraints:false];
          self.webView.frame = view.frame;
    }
  4. Cuối cùng, chỉ cần tải Url của bạn như thế này,

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

Cảm ơn đã đọc nó.


3

WebKit đã được giới thiệu trong iOS 8 nhưng nó đã được phát hành với một lỗi gây ra sự cố trong thời gian chạy, Nếu bạn đang sử dụng Xcode 9/10 , cấu hình dự án của bạn hỗ trợ ít hơn iOS 11 và nếu bạn đang cố gắng thêm WKWebView bằng trình tạo giao diện. Xcode ngay lập tức hiển thị lỗi thời gian biên dịch.

WKWebView trước iOS 11.0 (Hỗ trợ NSCoding đã bị hỏng trong phiên bản trước)

Mặc dù WKWebView đã được giới thiệu trong iOS 8 , nhưng có một lỗi trong - [WKWebView initWithCoder:] chỉ được sửa trong iOS 11 .

nhập mô tả hình ảnh ở đây

Độ phân giải là bạn phải thêm WKWebView thông qua mã (Chỉ khi bạn hỗ trợ bên dưới iOS 11). Điều đó thực sự nghe có vẻ lạ.

Một giải pháp khác là thay đổi Bản dựng tài liệu của Trình tạo giao diện cho tùy chọn sang iOS 11 trở lên (Nếu bạn đang di chuyển từ mục tiêu cũ sang iOS 11 và vẫn gặp lỗi tương tự).


1

// Dành cho 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)
}
}

// Đối với mục tiêu 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

nhập mô tả hình ảnh ở đây


0

Đây phải là một nhận xét về câu trả lời của Kampai, nhưng tôi không có đủ điểm danh tiếng để bình luận.

Bên cạnh các phiên bản iOS rõ ràng, trình đơn thả xuống 'Bản dựng cho' trong 'Trình kiểm tra tệp' cũng chứa tùy chọn Triển khai mục tiêu (..) . Tôi thích quản lý các phiên bản tại một nơi duy nhất nếu có thể và muốn thay đổi mục tiêu xây dựng bằng mọi cách. Tôi hoàn toàn bối rối khi vẫn nói Deployment Target (9.3) mặc dù tôi đã thay đổi mục tương ứng trong cài đặt chung thành 11.0 .

Việc khởi động lại XCode (11.3.1) là cần thiết để khiến mọi thứ hoạt động như mong đợi, tùy chọn 'Mục tiêu triển khai (11.0)' đã có sẵn (và 9.3 đã biến mất). Sau khi lựa chọn mọi thứ làm việc như expeected.


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 không được dùng trong iOS11 và WKWebView chỉ hoạt động trong iOS11 - điều này nghe có vẻ như là một lỗi trong Xcode GM.


Vâng. Cách giải quyết duy nhất tôi tìm thấy nếu bạn muốn triển khai trên phiên bản iOS trước đó là thêm WKWebView theo chương trình.
Mehdi Chennoufi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.