0

I'm developing a browser app. I'd like to restore WKWebView object when app is restarted. So I serialized WKWebView object and saved to Realm. But When I deserialized WKWebView object, the data of url and backList was losted from WKWebView.

let WebView = WKWebView()
WebView.frame = CGRect(x: 0, y: 0, width:300, height:650)
let urlString = "http://www.google.com"
let encodedUrlString = urlString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
let url = NSURL(string: encodedUrlString!)
let request = NSURLRequest(url: url! as URL)
WebView.load(request as URLRequest)

let serialized_WebView = NSKeyedArchiver.archivedData(withRootObject: WebView) as NSData //convert to NSData
let deserialized_WebView = NSKeyedUnarchiver.unarchiveObject(with: serialized_WebView as! Data) as! WKWebView

print("frame",deserialized_WebView.frame) // frame (0.0, 0.0, 300.0, 650.0)
print("url",deserialized_WebView.url) // url nil
print("backList",deserialized_WebView.backForwardList.backList) // backList []

I'd like to restore not only url but backList as a part of WKWebView object. I do not want to do implement unique function of save backList if possible.

Any advice please.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
oxygen
  • 165
  • 1
  • 1
  • 8

1 Answers1

4

I've honestly never seen anyone encode a view like this before. Generally speaking, views' conformance to NSCoding is intended for use by Interface Builder and any properties that can be set will probably be exposed there.

Looking in Interface Builder, the serialized properties are navigation gestures, user agent, link preview and a bunch of properties of WKWebViewConfiguration. I've confirmed in a breakpoint that this is all it encode.

The backList represents the state of the view at a given time and were it encoded it would be in WKWebView.encodeRestorableState(with:) for use in UIKit's state restoration process. Unfortunately, this method is not implemented and no state is saved. In this answer, matt recommends using UIWebView if you want to reconstruct history in a web view.

Another, more complex approach is what FireFox for iOS does. They do successfully restore history in a WKWebView using a trick with a custom web request server and a web page that injects URLs into the history via JavaScript's history.pushState. The relevant bits of code are:

This approach may work for one of the major players in the browser space, but it's probably not worth the trouble for most apps. I personally would recommend just sticking with a UIWebView and state restoration like matt suggested.

Brian Nickel
  • 26,890
  • 5
  • 80
  • 110