WKNavigationDelegate never called (Obj-C, macOS)

I'm adding a WKWebView to my (Mac) app, and it works fine except that the navigationDelegate is never called. Even stranger, if that delegate implements decidePolicyForNavigationAction, that method is never called either, but as a side effect the view now won't load any pages!

In detail: I've created a class implementing WKNavigationDelegate, I've implemented some of the methods, and assigned an instance to the view's navigationDelegate property. Easy stuff. I've done this in the past using the old-school WebView class. I've triple-checked my work.

As an experiment, I added a -respondsToSelector: method to my delegate class and made it log the selector. I see it being called several dozen times, with the selectors for all of the delegate methods and many other private(?) methods; so I know WebKit sees my object. It just never calls it at all.

My hunch so far is that this is an OS bug, that Apple no longer bothers to test WebKit APIs in Objective-C. I'd hate for that to be true.

(I realize Obj-C is basically deprecated nowadays. I'm using it because my non-UI code is all in C++, and it's vastly easier to integrate with C++ in Obj-C. To use Swift I'm going to have to wrap my API in C functions, yuck.)

  • Did you file a bug report and / or contact Support ?

  • Yes, I filed FB10015555 and FB10015541.

Add a Comment

Replies

Objective-C is not deprecated. It has been effectively cast aside, but the operating system will be built upon it for many years. However, I have heard of better C++ and Swift interoperability on the way.

WKNavigationDelegate works fine. I can't guess what problem you are having with it, but it works fine.

I realize Obj-C is basically deprecated nowadays.

I want to re-iterate nk_kennedy’s comment that Objective-C is most definitely not deprecated. While it does have some limitations when compared to Swift, the reverse is also true.

I'm using it because my non-UI code is all in C++, and it's vastly easier to integrate with C++ in Obj-C.

And that’s one of them! [1]


As to why your nav delegate isn’t working, it’s hard to say without looking at the code. I created a tiny test app to exercise this and it works for me. Specifically:

  1. Using Xcode 13.3.1 on macOS 12.3.1, I created a macOS app.

  2. I added a web view and wired it up to a webView property.

  3. I set the nav delegate as follows:

    self.webView.navigationDelegate = self;
    
  4. I wired up a Load button to this method:

    - (IBAction)loadAction:(id)sender {
        #pragma unused(sender)
        NSURL * url = [NSURL URLWithString:@"https://example.com"];
        NSURLRequest * req = [NSURLRequest requestWithURL:url];
        [self.webView loadRequest:req];
    }
    
  5. I implemented the decide-policy-for-navigation delegate:

    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
        NSLog(@"decide policy for navigation, action: %@", navigationAction);
        decisionHandler(WKNavigationActionPolicyAllow);
    }
    
  6. I ran the app and clicked the Load button. The web view loaded example.com.

  7. I clicked the “More information” link. My nav delegate method was called and printed:

    2022-05-12 11:10:57.425008+0100 xxom[65327:9142170] decide policy for navigation, action: … lots of stuff …
    

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Although that might change. If you’re interested in this topic, check out Swift Forums > Development > Announcements > Swift and C++ interoperability workgroup announcement. That stuff is cool!

  • Thanks as always, Quinn. I figured out after much experimentation that the problem isn't Obj-C. I was able to change my code to work correctly ... by switching from a nib-based UI to a storyboard-based one, of all things. No idea why this makes a difference, but:

    the storyboard-based UI uses an NSViewController instead of an NSWindowController, andthe WKWebView is now instantiated as the storyboard loads, not during the -applicationDidFinishLaunching: method as before.

    Less usefully, I also ported my initial Obj-C test code to Swift and it failed the same way.

    I filed two Radars, errr, "Feedback Reports", FB10015555 and FB10015541, each of which has a sample project attached. One of them demonstrates the delegate not being called, the other demonstrates a crash(!) if I use KVO to observe the webview's "title" property.

  • Glad you got it sorted out. And thanks for the bug numbers.

Add a Comment