为什么将从反序列化的 WKWebView 中删除 url
Why will be removed url from deserialized WKWebView
我正在开发浏览器应用程序。我想在应用程序重新启动时恢复 WKWebView 对象。所以我序列化了 WKWebView 对象并保存到 Realm。但是当我反序列化 WKWebView 对象时,url 和 backList 的数据从 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 []
我不仅要恢复 url,还要恢复 backList 作为 WKWebView 对象的一部分。如果可能的话,我不想实现保存 backList 的独特功能。
有什么建议吗
老实说,我以前从未见过有人像这样对 view 进行编码。一般来说,视图与 NSCoding 的一致性旨在供 Interface Builder 使用,并且可以设置的任何属性都可能在那里公开。
在 Interface Builder 中查看,序列化的属性是导航手势、用户代理、link 预览和 WKWebViewConfiguration
的一堆属性。我已经在断点中确认这就是它的全部编码。
backList
表示视图在给定时间的状态,如果对其进行编码,它将在 WKWebView.encodeRestorableState(with:)
中用于 UIKit 的状态恢复过程。不幸的是,这个方法没有实现,也没有保存状态。在 this answer 中,如果您想在 Web 视图中重建历史记录,matt 建议使用 UIWebView。
另一种更复杂的方法是 FireFox for iOS 所做的。他们使用自定义 Web 请求服务器的技巧和通过 JavaScript 的 history.pushState
将 URL 注入历史记录的网页成功地恢复了 WKWebView 中的历史记录。相关的代码位是:
Tab.restore(_:WKWebView)
:他们的代码获取一组 URL 并将事情交给他们的本地网络服务器。
- SessionRestoreHandler:returns 网页的本地 Web 服务器的请求处理程序。
- SessionRestore.html:请求处理程序提供的文件,它注入历史 JavaScript。
这种方法可能适用于浏览器中的主要播放器之一 space,但对于大多数应用程序来说可能不值得麻烦。我个人建议只坚持使用 UIWebView 并像 matt 建议的那样恢复状态。
我正在开发浏览器应用程序。我想在应用程序重新启动时恢复 WKWebView 对象。所以我序列化了 WKWebView 对象并保存到 Realm。但是当我反序列化 WKWebView 对象时,url 和 backList 的数据从 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 []
我不仅要恢复 url,还要恢复 backList 作为 WKWebView 对象的一部分。如果可能的话,我不想实现保存 backList 的独特功能。
有什么建议吗
老实说,我以前从未见过有人像这样对 view 进行编码。一般来说,视图与 NSCoding 的一致性旨在供 Interface Builder 使用,并且可以设置的任何属性都可能在那里公开。
在 Interface Builder 中查看,序列化的属性是导航手势、用户代理、link 预览和 WKWebViewConfiguration
的一堆属性。我已经在断点中确认这就是它的全部编码。
backList
表示视图在给定时间的状态,如果对其进行编码,它将在 WKWebView.encodeRestorableState(with:)
中用于 UIKit 的状态恢复过程。不幸的是,这个方法没有实现,也没有保存状态。在 this answer 中,如果您想在 Web 视图中重建历史记录,matt 建议使用 UIWebView。
另一种更复杂的方法是 FireFox for iOS 所做的。他们使用自定义 Web 请求服务器的技巧和通过 JavaScript 的 history.pushState
将 URL 注入历史记录的网页成功地恢复了 WKWebView 中的历史记录。相关的代码位是:
Tab.restore(_:WKWebView)
:他们的代码获取一组 URL 并将事情交给他们的本地网络服务器。- SessionRestoreHandler:returns 网页的本地 Web 服务器的请求处理程序。
- SessionRestore.html:请求处理程序提供的文件,它注入历史 JavaScript。
这种方法可能适用于浏览器中的主要播放器之一 space,但对于大多数应用程序来说可能不值得麻烦。我个人建议只坚持使用 UIWebView 并像 matt 建议的那样恢复状态。