original_username
original_username

Reputation: 2399

Swift extension "Method definition not found"

I'm writing a Swift extension to my ObjC class. Although my code compiles and runs perfectly, I'm getting a bunch of Xcode warnings (one per every Swift method):

  "Method definition for 'foo_method:' not found"
  "Method definition for 'bar_method:' not found"
  "Method definition for 'baz_method:' not found"

It's dead simple to reproduce the Xcode message. I made this demo project with four lines of non-boilerplate code:

Objective-C (subclass of NSView)

// Subclass_of_NSView.h

#import <Cocoa/Cocoa.h

@interface Subclass_of_NSView : NSView

@end


// Subclass_of_NSView.m

@implementation Subclass_of_NSView

- (instancetype)initWithFrame:(NSRect)frame
//______________^ WARNING: Method definition for resizeSubviewsWithOldSize: not found
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
    }
    return self;
}

@end

Swift (extends the Obj-C subclass)

// Extension_of_Subclass.swift

import Foundation

extension Subclass_of_NSView {

    override func resizeSubviewsWithOldSize( old_bounds_size:NSSize ) {

    }

}

Bridging-Header

// Demo_Project-Bridging-Header.h

#import "Subclass_of_NSView.h"

I'm guessing the warnings would go away if I either:

a) create a bunch of dummy methods in the .m file of my ObjC class.

b) in my Swift extension, extend my ObjC class's superclass.

I don't love either of these solutions.

Is there a better way to make the compiler happy?

Upvotes: 6

Views: 5013

Answers (2)

Yuchen
Yuchen

Reputation: 33036

This is an old question, but I am still seeing this problem with Xcode 7.3.1.

The reason why I cannot see the public function that is defined in the Objctive-C is because I didn't include all the class in the parameters in the bridge header. See the following example for more details:

I have class defined in Objective-C, like such:

Foo.h

@interface Foo : NSObject
- (void)function1;
- (void)function2:(Bar *)para; // here Bar is just another object
@end

Foo.m

@implementation Foo
// ...
@end

And in my bridge header I have #import "Foo.h" but not #import "Bar.h". As a result, I can call function1 from my swift extension but not function2.

Foo.swift

extension Foo {
    func function3() {
         function1(); // Okay
         function2(nil); // Method definition not found
    }
}

So, adding #import "Bar.h" to the bridge header solves the problem.

Upvotes: 2

Abhi Beckert
Abhi Beckert

Reputation: 33359

I'm not sure what's going on here, I think the problem is something to do with how NSView is bridged to the swift language.

If you're going to override those methods, make sure you call the super implementation, since NSView will probably break spectacularly without them. However I'm not sure if even this is safe, you might still break NSView — perhaps the reason the errors occur is because of some weird/non-standard setup Apple is doing.

If I was you, I'd just put up with the compiler warnings, and report the issue to Apple via http://bugreport.apple.com. Hopefully it will be fixed in a future beta release of Xcode 6.

Upvotes: 2

Related Questions