steven_noble
steven_noble

Reputation: 4203

Why is XCode giving me an 'unrecognized selector' error?

I'm developing a Mac app using Swift 2 and Xcode 7.

I'm just getting started with Swift after many years focused on Ruby with a touch of JavaScript.

The Mac app that I'm creating includes a web browser view.

My ViewController.swift says:

import Cocoa
import WebKit

class ViewController: NSViewController {

    @IBOutlet var url: NSTextField!
    @IBOutlet var browser: WKWebView!

    @IBAction func go(sender: AnyObject) {

        // browser.loadRequest(NSURLRequest(URL:NSURL(string: url.stringValue)!))
        // above line broken down for debugging

        let url1 = url.stringValue
        print("url1 = \(url1)")

        let url2 = NSURL(string: url1)!
        print("url2 = \(url2)")

        let url3 = NSURLRequest(URL:url2)
        print("url3 = \(url3)")

        print("browser is \(browser)")

        browser.loadRequest(url3)

    }
}

The app builds successfully. When I run it, enter http://apple.com into the URL field and click the Go button, I see:

url1 = http://apple.com
url2 = http://apple.com
url3 = <NSURLRequest: 0x600000001400> { URL: http://apple.com }
browser is <WebView: 0x608000120e60>
2016-04-06 13:39:51.664 Testivate[6516:427535] -[WebView loadRequest:]: unrecognized selector sent to instance 0x608000120e60
2016-04-06 13:39:51.664 Testivate[6516:427535] -[WebView loadRequest:]: unrecognized selector sent to instance 0x608000120e60
2016-04-06 13:39:51.667 Testivate[6516:427535] (
    0   CoreFoundation                      0x00007fff93f4a4f2 __exceptionPreprocess + 178
    1   libobjc.A.dylib                     0x00007fff8ca7a73c objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff93fb41ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x00007fff93eba571 ___forwarding___ + 1009
    4   CoreFoundation                      0x00007fff93eba0f8 _CF_forwarding_prep_0 + 120
    5   Testivate                           0x000000010000271a _TFC9Testivate14ViewController2gofPs9AnyObject_T_ + 2154
    6   Testivate                           0x00000001000027b6 _TToFC9Testivate14ViewController2gofPs9AnyObject_T_ + 54
    7   libsystem_trace.dylib               0x00007fff96e1807a _os_activity_initiate + 75
    8   AppKit                              0x00007fff94567e89 -[NSApplication sendAction:to:from:] + 460
    9   AppKit                              0x00007fff94579fde -[NSControl sendAction:to:] + 86
    10  AppKit                              0x00007fff94579f08 __26-[NSCell _sendActionFrom:]_block_invoke + 131
    11  libsystem_trace.dylib               0x00007fff96e1807a _os_activity_initiate + 75
    12  AppKit                              0x00007fff94579e65 -[NSCell _sendActionFrom:] + 144
    13  libsystem_trace.dylib               0x00007fff96e1807a _os_activity_initiate + 75
    14  AppKit                              0x00007fff9457848a -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2693
    15  AppKit                              0x00007fff945c0fd0 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 744
    16  AppKit                              0x00007fff94576bb4 -[NSControl mouseDown:] + 669
    17  AppKit                              0x00007fff94acb469 -[NSWindow _handleMouseDownEvent:isDelayedEvent:] + 6322
    18  AppKit                              0x00007fff94acc44d -[NSWindow _reallySendEvent:isDelayedEvent:] + 212
    19  AppKit                              0x00007fff9450b63d -[NSWindow sendEvent:] + 517
    20  AppKit                              0x00007fff9448bb3c -[NSApplication sendEvent:] + 2540
    21  AppKit                              0x00007fff942f2ef6 -[NSApplication run] + 796
    22  AppKit                              0x00007fff942bc46c NSApplicationMain + 1176
    23  Testivate                           0x0000000100004f34 main + 84
    24  libdyld.dylib                       0x00007fff9099a5ad start + 1
    25  ???                                 0x0000000000000003 0x0 + 3
)

Initially I thought the error was saying that loadRequest was an unrecognized selector for browser, but you can see I've pulled apart the function and browser is clearly an instance of WebView, which definitely has loadRequest as a method. You can see from how I've pulled apart the method that I'm definitely providing the loadRequest method with the expected NSURLRequest object.

I'm now thinking that maybe this has something to do with being unable to find the WebView in Main.storyboard, but surely it should be able to? I've defined connections on it like this:

Screenshot of Connections Inspector

When you view Main.storyboard as source, it says:

<webView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ocj-mD-woP">
    <rect key="frame" x="62" y="20" width="406" height="211"/>
    <webPreferences key="preferences" defaultFontSize="12" defaultFixedFontSize="12">
        <nil key="identifier"/>
    </webPreferences>
</webView>

Any thoughts? Thanks.

Upvotes: 1

Views: 1616

Answers (1)

Kurt Revis
Kurt Revis

Reputation: 27984

You're mixing up two different kinds of web views.

In your code, you're saying that browser is a WKWebView. That's the newer kind of web view, that was first available in OS X 10.10. It has a method named -loadView: in Objective-C, or loadView() in Swift.

@IBOutlet var browser: WKWebView!

However, when you run the code, the object is actually a WebView, because that's what you put in your storyboard. That's an older kind of web view. It doesn't have a method named -loadView: so you get an error when you try to call it.

browser is <WebView: 0x608000120e60>
-[WebView loadRequest:]: unrecognized selector sent to instance 0x608000120e60

(Read the documentation you linked to again. The WebView's main frame implements -loadRequest:, but WebView does not.)

Here are two possible fixes:

Easier: Fix your code to use WebView correctly, but leave the storyboard the same.

@IBOutlet var browser: WebView!
...
browser.mainFrame.loadRequest(url3)

Harder: Keep the code using WKWebView, but remove the WebView from your storyboard.

Unfortunately it's currently impossible to put a WKWebView in a storyboard, so you will have to write some code to set it up yourself. See the linked answer for an example of how to do it.

If you want to take advantage of the new features of WKWebView, you'll have to use the second alternative.

Upvotes: 2

Related Questions