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)
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. //
Swift File (FirstViewController.swift)
import UIKit class FirstViewController: UIViewController, test_delegate { var test : test_class! override func viewDidLoad() { super.viewDidLoad()
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:
This will cause problems with TestClass to be found in your Swift code. Correction:
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.