Objective-c protocol in swift issue - objective-c

I have a protocol in objective-c :
#protocol stuffDelegate <NSObject>
- (void) applyFiltersWithCuisines:(NSMutableArray *)cuisinesArray neighborhoods:(NSMutableArray *)neighborhoodsArray vibes:(NSMutableArray *) vibesArray;
#end
and i'm trying to use this method in swift :
func applyFiltersWithCuisines(cuisinesArray : NSMutableArray, neighborhoodsArray : NSMutableArray, vibesArray : NSMutableArray) -> () {
println("do stuff")
}
having issues in swift file :
Type 'controller' does not conform the protocol 'stuffDelegate', any ideas ?
So problem is that it looks different in swift

Your parameter names are different in the protocol and the method. The protocol defines
-applyFiltersWithCuisines:neighborhoods:vibes:
The ObjectiveC signature of your Swift method (the #selector) would be
-applyFiltersWithCuisines:neighborhoodsArray:vibesArray:
They don't match.

Related

How to implement objective C protocol in swift class?

#protocol LibraryPaymentStatusProtocol <NSObject>
#required
-(void)paymentStatus:(NSString*)message;
#optional
-(void)onError:(NSException *)exception;
-(void)tryAgain;
-(void)cancelTransaction;
#end
This protocol I want to implement in my swift class. This protocol is present in BDViewController.h file which is inside the Library. I imported the library successfully in my swift project not getting access to this protocol. What is the additional thing I am missing? Thanks in advance.
In my Swift class, I simply want to implement like normal protocol like below
class mainTabViewController: LibraryPaymentStatusProtocol {
// MARK : - Payment status protocol method
func paymentStatus(_ message: String!) {
}
}
Add this line in the bridging header
#import "BDViewController.h"
maybe it will solve your problem. Let me know if it is helpful.
You need to create a Swift bridging header and include your Objective-C file there.
// <ProjectName>-Bridging-Header.h
#import "BDViewController.h" // In which you have written LibraryPaymentStatusProtocol
Then you can implement the required method as
func paymentStatus(_ message: String?) {
}

iOS11 Swift 4 - how to check if Swift class conforms to protocol defined in Objective-C?

I have a legacy code base with code written in Objective-C. I'm adding a new class written in Swift which has to conform to existing protocols defined in Objective-C.
How can I make sure my Swift class correctly implements methods defined in Objective-C protocol?
//In Obj-C
#protocol OBJCLocationObserver <NSObject>
- (void)didUpdateLocationWithModel:(nullable Model *)locationModel
lastLocation:(CLLocationCoordinate2D)lastLocation;
#end
//In Swift
extension SwiftLocationManager : OBJCLocationObserver
{
public func didUpdateLocation(with model: Model?, lastLocation: CLLocationCoordinate2D) {
// How to verify this function signature is actually conforming to the Obj-C protocol and is not a new method?
}
}
[MyClass conformsToProtocol:#protocol(MyProtocol)];
According to Apple Docs you can use conformsToProtocol:which returns a Boolean value that indicates whether the receiver conforms to a given protocol.
Example
#protocol MyProtocol
- (void)helloWorld;
#end
#interface MyClass : NSObject <MyProtocol>
#end
Will be exposed as:
console.log(MyClass.conformsToProtocol(MyProtocol));
var instance = MyClass.alloc().init();
console.log(instance.conformsToProtocol(MyProtocol))
Make sure you #import your protocol definition file into the <ProjectName>-Bridging-Header.h file:
#import "OBJCLocationObserver.h"
And then you should see error messages if your signature does not match.
You can also use Xcode Auto Completion. Type:
public func didUpdateLocation
and Auto Complete suggests:
public func didUpdateLocation(withModel Model?, lastLocation: CLLocationCoordinate2D)
which is different than what you have and explains why it isn't working.
Here is another way to get the interface:
As #MartinR suggested on a comment to another question:
Go to the header file where the protocol is defined, and choose
"Generated Interface" from the "Related Items" popup in the top-left
corner. That will show you the exact Swift method signature that you
have to implement.

Can not find Swift Protocol declaration in Obj-C class

I have created on Class in Swift and that class and its protocol I am using in Obj-C enabled project but I am getting below error while compiling my project.
cannot find protocol declaration for 'SpeechRecognizerDelegate'; did
you mean 'SFSpeechRecognizerDelegate'?
Can anyone guide me on this how can I use Swift class protocol in my Obj-C class.
Here is my Swift code:
protocol SpeechRecognizerDelegate : class {
func speechRecognitionFinished(_ transcription:String)
func speechRecognitionError(_ error:Error)
}
class SpeechRecognizer: NSObject, SFSpeechRecognizerDelegate {
open weak var delegate: SpeechRecognizerDelegate?
}
Protocol use in Obj-C:
#import "ARBot-Swift.h"
#interface ChatScreenViewController : JSQMessagesViewController <SpeechRecognizerDelegate>
Let me know if required more info.
Thanks in Advance.
in Swift:
#objc public protocol YOURSwiftDelegate {
func viewReceiptPhoto()
func amountPicked(selected: Int)
}
class YourClass: NSObject {
weak var delegat: YOURSwiftDelegate?
}
in Objective-C headerFile.h
#protocol YOURSwiftDelegate;
#interface YOURController : UIViewController < YOURSwiftDelegate >
in Objective-C Implementation.m
SwiftObject * swiftObject = [SwiftObject alloc] init];
swiftObject.delegate = self
Define your Swift protocol like this inside your Swift file.
#objc protocol SpeechRecognizerDelegate: class{
func speechRecognitionFinished(_ transcription:String)
func speechRecognitionError(_ error:Error)
}
Create a Swift Module inside your project setting then use it. You can find here complete blog for the mix language coding.
Then use Protocol inside Objective C class,
We required to add protocol inside Objective C file -
#import "ARBot-Swift.h"
#interface ChatScreenViewController : JSQMessagesViewController <SpeechRecognizerDelegate>
Then you need to conform to the protocol methods -
- (void)viewDidLoad {
[super viewDidLoad];
SpeechRecognizer * speechRecognizer = [[SpeechRecognizer alloc] init];
speechRecognizer.delegate = self;
}
#pragma mark - Delegate Methods
-(void)speechRecognitionFinished:(NSString *) transcription{
//Do something here
}
-(void)speechRecognitionError:(NSError *) error{
//Do something here
}
I had a similar issue after following (import header + Objc annotation on protocol). I got the warning when using Swift code from Objective C headers. Solved by only importing into the implementation .m files.
Add #objc attribute to your protocol:
#objc protocol SpeechRecognizerDelegate : class {
//...
}
Include Swift Classes in Objective-C Headers Using Forward Declarations
//MySwiftClass.swift
#objc protocol MySwiftProtocol {}
#objcMembers class MySwiftClass {}
// MyObjcClass.h
#class MySwiftClass;
#protocol MySwiftProtocol;
#interface MyObjcClass : NSObject
- (MySwiftClass *)returnSwiftClassInstance;
- (id <MySwiftProtocol>)returnInstanceAdoptingSwiftProtocol;
// ...
#end

Swift & Objective C protocols: throwing function declaration [duplicate]

I have Objective-C Protocol
#protocol SomeObjCProtocol
- (BOOL) doSomethingWithError: (NSError **)error;
#end
And Swift class
class SwiftClass : SomeObjCProtocol
{
func doSomething() throws {
}
}
Compilers gives me an error
Type 'SwiftClass' does not conform to protocol 'SomeObjCProtocol'"
Is there any solution how to get rid of this error?
I'm using XCode 7 Beta 4
There are two problems:
Swift 2 maps func doSomething() throws to the Objective-C method
- (BOOL) doSomethingAndReturnError: (NSError **)error;, which is
different from your protocol method.
The protocol method must be marked as "Objective-C compatible" with the #objc attribute.
There are two possible solutions:
Solution 1: Rename the Objective-C protocol method to
#protocol SomeObjCProtocol
- (BOOL) doSomethingAndReturnError: (NSError **)error;
#end
Solution 2:
Leave the Objective-C protocol method as it is, and specify the Objective-C mapping for the Swift method
explicitly:
#objc(doSomethingWithError:) func doSomething() throws {
// Do stuff
}
When encountering that error message, one source of the problem might be that the Swift class conforming to the Objetive C protocol was not inherited from NSObject.

Pass #protocol type in Swift

I have an Objective-C method which takes Protocol* type as parameter.
How can I invoke this method in Swift.
Example:
// In Objective-C
#protocol AProtocol <NSObject>
#end
#interface MyClass : NSObject
+ (id)proxyWithProtocol:(Protocol*)protocol;
#end
// I can call this method with a protocol as parameter
[MyClass proxyWithProtocol:#protocol(AProtocol)];
If I want to use MyClass in Swift by bridging. How can I pass a protocol defined in Objective-C to proxyWithProtocol method. Can I even pass a protocol defined in Swift to this method?
You would pass the Objective-C protocol in like so:
MyClass.proxyWithProtocol(AProtocol)
If you wanted to pass in a Swift protocol, you would have to expose that protocol to Objective-C:
#objc protocol MyProtocol {
func someGreatFunc()
}
// ...
MyClass.proxyWithProtocol(MyProtocol)
In Swift 3, depending on the way the class is bridged to Swift, your function might look like this:
MyClass.proxy(with: AProtocol)
MyClass.proxy(with: MyProtocol)
Although the compiler isn't happy with the location of "with" and may complain.