I am trying to write a protocol in swift
@objc protocol RestAPIManagerDelegate {
optional func credentialValidated(isValid: Bool?)
}
But I am getting following error:
'Method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C'
Any suggestion?
Objective-C Language Protocols Optional and required methods This means that any class that conforms to this protocol must implement those methods. It is also possible to declare optional methods. These method can be implemented only if needed. You mark optional methods with the @optional directive.
Optional binding The code let booleanValue = booleanValue returns false if booleanValue is nil and the if block does not execute. If booleanValue is not nil , this code defines a new variable named booleanValue of type Bool (instead of an optional, Bool? ).
Boolean, in Objective-C, is a hold over data type from the C language. Both in C, and hence in Objective-C, 0 (zero) is treated as “false” and 1 (one) as “true”. C has a Boolean data type, bool (note: the lowercase), which can take on the values of true and false.
It's OK to use NSNumber?
instead, but there is another way.
You can create OptionalBool
enum and use it instead of Bool?
for compatibility with Objective-C.
Creating OptionalBool
enum in Swift code:
@objc enum OptionalBool: Int {
case none
case yes
case no
}
@objc protocol RestAPIManagerDelegate {
@objc optional func credentialValidated(isValid: OptionalBool)
}
Using OptionalBool
in Objective-C code:
@interface RestAPIManagerHandler () <RestAPIManagerDelegate>
@end
@implementation RestAPIManagerHandler
- (void)credentialValidatedWithIsValid:(enum OptionalBool)isValid {
switch (isValid) {
case OptionalBoolYes:
NSLog(@"TRUE");
break;
case OptionalBoolNo:
NSLog(@"FALSE");
break;
case OptionalBoolNone:
NSLog(@"NULL");
break;
}
}
@end
The problem is this type declaration:
`isValid: Bool?`
That is perfectly fine in Swift. But you cannot expose it to Objective-C, because Objective-C does not have any notion of an Optional BOOL - a BOOL in Objective-C is basically just a number, a primitive C datatype (what we call a scalar).
Here's another way of looking at it. In an interchange with Objective-C, you can use a Swift Optional anywhere that Objective-C can say nil
- indeed, to a large extent Swift Optional exists exactly in order to deal with the possibility that Objective-C will say nil
or that you might need to say nil
to Objective-C. But a BOOL in Objective-C can never be nil
- it can only be YES or NO (Swift true
or false
).
So you have three choices:
Take away the @objc
that exposes all this to Objective-C
Remove the Optional and just declare that type a Bool
Use an object type. For example, declare the type as AnyObject?
(or NSNumber?
). This will work because Swift will bridge a Bool to an NSNumber (including as it passes into an AnyObject), and Objective-C will deal just fine with an Optional AnyObject or Optional NSNumber because those are object types, not scalars.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With