Xcode 9 GM-이전 버전에서 WKWebView NSCoding 지원이 중단되었습니다.


155

누구든지 Xcode 9 GM 으로이 오류를 해결하는 방법을 알고 있습니까? Xcode 8.3으로 만든 앱을 작업 중이며 배포 대상은 iOS 9.3이며 이전에는이 ​​문제가 없었습니다. 여기 또는 Apple 포럼에서 정보를 찾지 못했습니다 :(

편집 :이 오류는 프로그래밍 방식으로 사용하지 않고 WKWebView를 인터페이스 빌더에 넣을 때 발생했습니다.

그림 WKWebView 오류 참조

편집 2 : 마침내 버그는 아닙니다.이 동작에 대한 자세한 내용은 아래 Quinn의 답변을 참조하십시오. 설명해 주셔서 감사합니다.


1
아래 답변을 참조하십시오. 이것은 Xcode 9의 버그가 아닙니다. 이 빌드 오류가 없으면 대신 iOS 11 이전의 런타임에서 -initWithCoder에서 충돌이 발생합니다.
Quinn Taylor

1
난 그냥 11에 내 배포 대상을 변경
웨이

답변:


160

오류는 올바른 동작이며 Xcode 9의 버그는 아닙니다. iOS 8에서는 WKWebView가 도입되었지만 -[WKWebView initWithCoder:]iOS 11에서만 수정 된 버그가있었습니다. 버그 는 런타임시 항상 충돌하여 Interface Builder 내 에서 버그를 구성 할 수 없었습니다.

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

개발자가 런타임에 깨질 IB에서 무언가를 빌드하는 대신 빌드 오류입니다. iOS 11이 최근에 출시 된 이래로 불편한 한계가 있지만 실제로 다른 좋은 옵션은 없습니다.

이전 배포 대상의 해결 방법은 @ fahad-ashraf가 이미 그의 답변에서 설명한 것처럼 코드에 WKWebView를 계속 추가하는 것입니다.

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


3
안녕 퀸, 나는 애플에서 일하는 사람이 :-) 나는 또한 그것에 대해 당신의 버그 리포트를 발견 믿습니다 lists.webkit.org/pipermail/webkit-unassigned/2014-September/...는 정말 새에 대한 놀라운 답변에 감사드립니다 우리는 그런 행동을 겪을 때 저를 좋아합니다. 다시 감사합니다.
Mehdi Chennoufi

감사합니다! 유용했습니다.
ssowri1

2
ios10에서도 지원하려면 어떻게해야합니까?. 내 응용 프로그램에서 iOS 10도 지원해야합니다.이 문제를 어떻게 해결할 수 있습니까?
Kalikanth040494

iOS 11까지 애플이 왜 해결책을 찾아야했는지 궁금한가?
Eman

96

이것은 Xcode 9의 버그로 보이며 베타에도 존재했습니다. 스토리 보드를 통해 WKWebView를 작성하는 경우에만 빌드 오류가 발생합니다. 해당 ViewController 클래스 파일에서 WKWebView를 프로그래밍 방식으로 생성하는 경우 iOS 11 이하의 iOS 버전에서 빌드 할 수 있어야합니다. 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()시작에 있어야합니다. 그것 없이는 아무것도 보이지 않습니다.
Makalele

안녕 :), webview내 탐색 모음 아래 에이 제약 조건을 설정하는 방법을 알고 있습니까? 이 솔루션은 효과가 있지만 전체 화면을 다룹니다.
Abed Naseri

@AbedNaseri 제약 조건을 넣을 필요가 없다고 생각합니다 ... 스토리 보드를 인스턴스화 한 다음 self.navigationController? .pushViewController (youVC, animated : true) 할 수 있습니다.
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)
    }

정말 감사합니다. 정말 도움이됩니다. 그것은 애플에 의해
알려진

1
일했다! iOS 11 및 swift 4.1에서 테스트
Alwin

2
오류가 발생 [LayoutConstraints] Unable to simultaneously satisfy constraints하면 줄을 잊지 마십시오 webView.translatesAutoresizingMaskIntoConstraints = false. 이 속성을 true로 설정 webView하면 프로그래밍 방식으로 추가 한 제약 조건과 충돌하는 자동으로 전체 제약 조건 집합이 생성 됩니다. 애플 문서 .
mogelbuster

51

이전 대상에서 iOS 11.0으로 이동했지만 여전히이 오류가 발생하면 아래 해결책을 사용하십시오.

  1. 스토리 보드 (Main.storyboard)로 이동하여 장면을 클릭하십시오.
  2. Xcode의 오른쪽 속성 창인 'File Inspector'를 선택하십시오.
  3. ' Builds for '값을 ' iOS 11.0 이상 '으로 변경
  4. 컴파일 및 빌드

여기에 이미지 설명을 입력하십시오


2
@ VyachaslavGerchicov : 나는 당신에 대해 모르지만, 업계에는 새로운 기술로 전환 해야하는 오래된 프로젝트가 있습니다. 많은 사람들이 같은 문제에 직면하고 있습니다. 나는 대답에서 이미 "이전 목표에서 벗어나면"이라고 언급했습니다. 하나의 사례 만 생각하지 마십시오.
Kampai

1
이 성가신 IB 설정을 지적 해 주셔서 감사합니다. 경고가 바로 사라졌습니다. 실제로, 나는 이것이 더 실용적이라고 생각하고 대답해야합니다. 애플은 자신의 기본 프레임 워크 계속 변경 이후 실제로, 우리는 아이폰 OS의 새 버전으로 이동하도록 강요, @Kampai에 동의
infinity_coding7을

iOS 10.x 앱으로 시뮬레이터에서 실행할 때 수행하면 충돌이 발생합니다.
Ramis

@Ramis : iOS 10에서하고 있었는데 앱 충돌이 없었습니다. 충돌 로그는 무엇입니까?
Kampai

1
이 문제를 해결하기위한 가장 간단한 솔루션입니다. 감사!
Jerry Chong

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. 이제 새로 작성된 webView를 다음과 같이 containerView에 추가하십시오.

    -(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는 즉시 컴파일 타임 오류를 보여줍니다.

iOS 11.0 이전의 WKWebView (이전 버전에서는 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)
}
}

// 목표 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

여기에 이미지 설명을 입력하십시오


0

이것은 Kampai의 답변에 대한 의견이어야하지만 언급 할 평판이 충분하지 않습니다.

명시적인 iOS 버전 외에 '파일 검사기'의 '빌드 대상'드롭 다운에는 배포 대상 (..) 옵션 도 포함되어 있습니다. 가능하면 한 곳에서 버전을 관리하는 것을 선호하고 빌드 대상을 변경하고 싶었습니다. 일반 설정의 해당 항목을 11.0 으로 변경했지만 배포 대상 (9.3) 이라고 여전히 혼란 스럽습니다 .

모든 것이 예상대로 작동하려면 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를 추가하는 것입니다.
Mehdi Chennoufi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.