I think this is a sensible approach.
A) Offer a nice, high-level, safe API for commonly used cases like page
event listeners, tab change listener etc.. It abstracts away
implementation details for that code that doesn't care about it, esp.
extensions, but also other browser code. It just keeps your code clean.
B) Still allow access to the underlying WKWebView API. This helps
1) your ready-made components that depend on WKWebView and
2) obscure one-off code that needs particular WKWebView functionality.
(As soon as you would get 2-3 callers of the 2) type, you'd make a
higher-level API of the A) style.)
Heath Borders wrote, On 11.12.2014 20:53:
> I agree with using WKWebView as a first-class citizen, however, I
> suggest you implement callbacks with a custom delegate that wraps KVO
> instead of injecting KVO code everywhere. KVO is very easy to get
> wrong. I've seen lots of bugs where people forget to remove observers,
> or they attempt to remove observers at the wrong point in an object's
> lifecycle, which unfortunately will cause a crash many run loops
> later, if at all. :(
>
> Also, you must observe based on a context and property name rather
> than just a property name (you could also use multiple contexts). In
> your example code:
>
> > var webView: WKWebView? {
> > willSet (newWebview) {
> > if let wv = self.webView {
> > for keyPath in observedKeyPaths {
> > wv.removeObserver(self, forKeyPath: keyPath)
> > }
> > }
> > }
> > didSet {
> > for keyPath in observedKeyPaths {
> > webView?.addObserver(self, forKeyPath: keyPath,
> options: NSKeyValueObservingOptions.New, context: nil)
> > }
> > }
> > }
>
> > override func observeValueForKeyPath(keyPath: String,
> >
> ofObject object: AnyObject,
> >
> change: [NSObject : AnyObject],
> >
> context: UnsafeMutablePointer<Void>) {
> > switch keyPath {
> > case "URL":
> > if let url = change[NSKeyValueChangeNewKey] as? NSURL {
> > self.text = url.absoluteString
> > }
> > case "hasOnlySecureContent":
> > if let hasOnlySecureContent =
> change[NSKeyValueChangeNewKey] as? Bool {
> > self.layer.backgroundColor = hasOnlySecureContent ?
> UIColor.greenColor().CGColor : UIColor.whiteColor().CGColor
> > }
> > default:
> > super.observeValueForKeyPath(keyPath, ofObject:
> object, change: change, context: context)
> > }
> > }
>
> If someone subclasses LocationTextField (I know it's private now, but
> refactorings happen all the time), they might also observe "URL" or
> "hasOnlySecureContent", and they'll get double-notified. Worse, when a
> subclass calls removeObserver with only a keyPath rather than with a
> keyPath and context, either LocationTextField or a subclass will crash
> because removeObserver:forKeyPath: removes all observers at that
> keyPath, and a second call when there are no observations will crash.
>
> I'm not trying to tear down this particular code sample because it's
> just an example, but I'm trying to communicate that it is much harder
> to write correct KVO code compared to simply providing a weak delegate
> which will be safely nilled thanks to ARC.
>
> -Heath Borders
> [email protected] <mailto:[email protected]>
> Twitter: heathborders
> http://heath-tech.blogspot.com
>
> On Thu, Dec 11, 2014 at 11:53 AM, Stefan Arentz <[email protected]
> <mailto:[email protected]>> wrote:
>
> There was a discussion yesterday on IRC about abstracting/hiding
> WKWebView. I would like to make a counter argument here and
> suggest we embrace the the WKWebView APIs fully and not try to
> hide its existence.
>
> Currently we have wrapped WKWebView in a Browser object. The
> Browser has functions like canGoBack() and goBack(). I think this
> is redundant because these map 1:1 to the WKWebView.
>
> This adds a layer of complexity that we don’t need. Instead I
> would like to be able to freely access the WKWebView and for
> example use Key-Value Observing to update user interface elements
> (and internal logic) when the WKWebView’s state has changed.
>
> A good example of the power of directly talking to the WKWebView
> combined with KVO is this:
>
>
>
> https://gist.github.com/st3fan/df6e470f177044a41436#file-gistfile1-swift-L123
>
> Here we have a LocationTextField that only needs to know what
> WKWebView it is currently connected to. It then starts observing
> for URL changes and security changes and updates its UI
> accordingly. The URL is now always up to date and when the page
> has secure content, the location field turns green. Look how
> little code this is. This is the Cocoa way of doing things. If we
> abstract away the WKWebView then we are basically going to
> reinvent all of this by introducing delegates and extra
> infrastructure code to do what the framework is already giving us.
>
> The same mechanism can be used for progress tracking, keeping
> back/forward button state correct, showing a title, acting on page
> loads and a bunch more things.
>
> I think we should realize that WKWebView is the way forward on
> iOS. UIWebView will likely be deprecated by iOS9 (which is summer
> next year) and Gecko will never happen on this platform because
> the App Store forbids it. So lets use WKWebView as a first class
> object and take advantage of the things it gives us.
>
> What do you think?
>
> S.
>
> _______________________________________________
> mobile-firefox-dev mailing list
> [email protected] <mailto:[email protected]>
> https://mail.mozilla.org/listinfo/mobile-firefox-dev
>
>
>
>
> _______________________________________________
> mobile-firefox-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/mobile-firefox-dev
_______________________________________________
mobile-firefox-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/mobile-firefox-dev