iOS11
WKWebview
NSInvalidUnarchiveOperationException
app crash
debugging

iOS11 WKWebview crash due to NSInvalidUnarchiveOperationException

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

NSInvalidUnarchiveOperationException around WKWebView on iOS 11 usually points to archived state that can no longer be decoded safely. In practice, the crash often appears when an app persists or restores WKWebView-related objects with NSKeyedArchiver, NSUserDefaults, state restoration, or an older nib or storyboard configuration that no longer matches the runtime expectations.

The fix is usually not "patch WKWebView itself." The fix is to stop persisting the wrong objects, clear incompatible archived state, and rebuild the web view from safe primitive values such as URLs or plain configuration flags.

What The Exception Usually Means

NSInvalidUnarchiveOperationException is thrown when the unarchiver cannot decode the archived payload into the classes it expects. On iOS 11, secure coding behavior and stricter decoding paths exposed crashes that had previously remained hidden.

With WKWebView, the risky pattern is usually archiving complex objects directly. WKWebView, WKProcessPool, and other web-view infrastructure objects are not good candidates for long-term persistence in UserDefaults or ad hoc archives. Persist the minimal inputs you need to recreate the view, not the live view object graph itself.

Persist Safe Data, Not The Web View Object

A bad pattern looks like trying to archive the full web view or related complex objects:

swift
let data = try NSKeyedArchiver.archivedData(withRootObject: webView, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "savedWebView")

That is fragile and often wrong. A safer approach is to persist only the URL or other simple state:

swift
1import WebKit
2
3let urlString = webView.url?.absoluteString
4UserDefaults.standard.set(urlString, forKey: "lastLoadedURL")

Then rebuild the WKWebView cleanly on launch:

swift
1import UIKit
2import WebKit
3
4class ViewController: UIViewController {
5    private var webView: WKWebView!
6
7    override func viewDidLoad() {
8        super.viewDidLoad()
9
10        let config = WKWebViewConfiguration()
11        webView = WKWebView(frame: view.bounds, configuration: config)
12        view.addSubview(webView)
13
14        if let raw = UserDefaults.standard.string(forKey: "lastLoadedURL"),
15           let url = URL(string: raw) {
16            webView.load(URLRequest(url: url))
17        }
18    }
19}

This avoids trying to deserialize internal WebKit state that should not be persisted that way.

Watch State Restoration And Old Archives

Even if your current code is correct, old archived data may still be sitting on the device from earlier builds. That is why the crash sometimes appears only on upgraded installs and not on fresh installs. If the archive format changed, the app may try to decode data that no longer matches the expected class graph.

A practical mitigation is to detect the bad archive path and clear the old stored value:

swift
UserDefaults.standard.removeObject(forKey: "savedWebView")

For production apps, this kind of cleanup is often part of a migration step. Old persisted state can outlive the code that created it.

Use Modern Secure-Coding APIs Carefully

iOS 11 pushed more code paths toward secure decoding. If you are archiving your own model objects that interact with web-view state, those objects should adopt NSSecureCoding correctly rather than relying on looser legacy behavior.

swift
1final class SavedPage: NSObject, NSSecureCoding {
2    static var supportsSecureCoding: Bool { true }
3
4    let urlString: String
5
6    init(urlString: String) {
7        self.urlString = urlString
8    }
9
10    required init?(coder: NSCoder) {
11        guard let value = coder.decodeObject(of: NSString.self, forKey: "urlString") as String? else {
12            return nil
13        }
14        urlString = value
15    }
16
17    func encode(with coder: NSCoder) {
18        coder.encode(urlString, forKey: "urlString")
19    }
20}

Notice what is being archived here: a simple, stable model value, not a live WebKit object.

Debug The Real Source Of The Archive

When the stack trace mentions WKWebView, it is easy to assume WebKit itself is randomly failing. Often the actual problem is your app's persistence layer or a framework that stores view state on your behalf. Look at where unarchiving happens, what keys are involved, and whether the crash disappears on a clean install. Those clues usually tell you whether you are dealing with stale app data, bad secure-coding conformance, or an unsupported archive target.

Common Pitfalls

One common mistake is trying to archive the WKWebView itself or other complex WebKit objects. Another is forgetting that upgraded users may still have old incompatible archives even after the code is fixed. Developers also sometimes store rich objects in UserDefaults when a URL string or small model would be enough. Finally, secure-coding migrations can expose bugs that were already present, so a crash that starts on iOS 11 is not always a new WebKit defect. It is often an old persistence bug becoming visible.

Summary

  • 'NSInvalidUnarchiveOperationException usually means archived state cannot be decoded safely.'
  • Do not archive WKWebView or other complex WebKit objects directly.
  • Persist simple values such as URLs and recreate the web view at runtime.
  • Clear or migrate stale archived data when users upgrade from older app versions.
  • If you archive your own objects, implement secure coding correctly and keep the archived model simple.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions