Objective-c for the Swift class. unrecognized method

I'm trying to port some code from Objective-c to Swift, but I have problems at the beginning when I want to combine the Swift class with the Objective-c protocol and access this class from the objetive-c class. I am doing something wrong, but I do not see it.

Objective-c protocol and obj-c class for testing (test_class.h)

#import <Foundation/Foundation.h> @protocol test_delegate -(void)returnData:(NSString*)data InMethod:(NSString*)method; @end @interface test_class : NSObject @property (weak, nonatomic) id<test_delegate> delegate; -(void)sendData:(NSString * )data; @end 

Objective-c implementation

 #import "test_class.h" @implementation test_class -(id) init{ self = [super init]; if (self != nil){ self.delegate= nil; } return self; } -(id) initWithDelegate:(id<test_delegate>) delegate{ self = [super init]; if (self != nil){ self.delegate = delegate; } return self; } -(void)sendData:(NSString *)data{ [self.delegate returnData:data InMethod:@"method test"]; } @end 

Shared file with team

 // // Use this file to import your target public headers that you would like to expose to Swift. // #import "test_class.h" 

Swift File (FirstViewController.swift)

 import UIKit class FirstViewController: UIViewController, test_delegate { var test : test_class! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. test = test_class() test.delegate=self test.sendData("show in log") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func returnData(data: String!, inMethod method: String!) { NSLog(data) } } 

Finally, compiling errors gives me

 2015-01-27 08:21:05.787 Test[4566:51164] -[Test.FirstViewController returnData:InMethod:]: unrecognized selector sent to instance 0x7fa6abd0aa20 2015-01-27 08:21:05.792 Test[4566:51164] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Test.FirstViewController returnData:InMethod:]: unrecognized selector sent to instance 0x7fa6abd0aa20' 

This code, using only the Obj-c classes, works great. What am I doing wrong?

Using Xcode 6.1.1 and iOS 8.0 Deployment Goals

Thanks in advance.

UPDATE: Swift has a weird behavior when implementing any method from the Objective-c protocol: the parameter name must begin with a tiny letter in the begginig code, otherwise the compiler will give you a compile-time error, and if not, give you a runtime error.

The only solution I found was to define an Objective-c protocol method as follows:

 @protocol test_delegate -(void)returnData:(NSString*)data InMethod:(NSString*)method; @end 

in

 @protocol test_delegate -(void)returnData:(NSString*)data InMethod:(NSString*)method; @end 

Performing this change, it works great.

If someone has an answer to this behavior, you can post messages and explain why this is happening.

UPDATE 2: Thanks @Adam Freeman for pointing out another weird Swift problem with class names and variable names. The code is copied (with his permission) here:

Another thing to consider is if your protocol delegation method accepts its class as one of its parameters. Using this example:

 #import <Foundation/Foundation.h> @class TestClass; @protocol TestDelegate -(void)TestClass:(TestClass*)TestClass returnData:(NSString*)data inMethod:(NSString*)method; @end @interface TestClass : NSObject @property (weak, nonatomic) id<TestDelegate> delegate; -(void)sendData:(NSString * )data; @end 

This will cause problems with TestClass to be found in your Swift code. Correction:

 #import <Foundation/Foundation.h> @class TestClass; @protocol TestDelegate -(void)TestClass:(TestClass*)TestClass returnData:(NSString*)data inMethod:(NSString*)method; @end @interface TestClass : NSObject @property (weak, nonatomic) id<TestDelegate> delegate; -(void)sendData:(NSString * )data; @end 

By the way, the Swift specification states that things like classes and delegates should begin with an uppercase letter, and methods and parameter names must begin with a lowercase letter.

+7
ios objective-c swift protocols delegates
source share
2 answers

Edit:

 func returnData(data: String!, inMethod method: String!) { 

to

 func returnData(data: String!, inMethod method: String!) { 

and it should work. You are using a capital letter in inMethod .

+6
source share

Another thing that I need to pay attention to is that I came across and this post helped me fix (thanX!) And that others may come across this - if your protcol delegation method accepts its class as one of its parameters. For example, ==>

 #import <Foundation/Foundation.h> @class TestClass; @protocol TestDelegate -(void)TestClass:(TestClass*)TestClass returnData:(NSString*)data inMethod:(NSString*)method; @end @interface TestClass : NSObject @property (weak, nonatomic) id<TestDelegate> delegate; -(void)sendData:(NSString * )data; @end 

This will cause problems with TestClass to be found in your Swift code. Correction:

 #import <Foundation/Foundation.h> @class TestClass; @protocol TestDelegate -(void)TestClass:(TestClass*)TestClass returnData:(NSString*)data inMethod:(NSString*)method; @end @interface TestClass : NSObject @property (weak, nonatomic) id<TestDelegate> delegate; -(void)sendData:(NSString * )data; @end 

By the way, the Swift specification states that things like classes and delegates should begin with an uppercase letter, and methods and parameter names must begin with a lowercase letter. I know this is nit-picky, but test_class really should be TestClass according to Apple specification.

+1
source share

All Articles