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]
Twitter: heathborders
http://heath-tech.blogspot.com
On Thu, Dec 11, 2014 at 11:53 AM, Stefan Arentz <[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]
> https://mail.mozilla.org/listinfo/mobile-firefox-dev
>
_______________________________________________
mobile-firefox-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/mobile-firefox-dev