Checking if Any.Type conforms to a protocol in Swift
To check the pure Swift code, you can do:
protocol MySwiftProtocol: AnyObject {
}
class MySwiftClass: MySwiftProtocol {
}
if MySwiftClass.self as? MySwiftProtocol.Type != nil {
print("conforms")
} else {
print("does not conform")
}
or more simply:
if MySwiftClass.self is MySwiftProtocol.Type {
Check if class conforms to protocol
If you import obj-c then you can do something like you used to.
Otherwise, it's hard because protocols don't exist in the same way. Consider a registration based system for your factory. Each of your classes would register themselves by supplying a function or closure that can be called to return a new instance of that class, and the registration is against a string or some other type of identifier. This is where it would be good to have a protocol type, but in obj-c you were really doing the same thing with a string conversion. You could register against anything that is Equatable
to keep things very generic.
Checking if a Swift class conforms to a protocol and implements an optional function?
You are still thinking in Objective-C, embrace Swift!
Assuming that your protocol looks like this:
@objc protocol SKPhysicsContactDelegate {
optional func didBeginContact()
}
Try this:
if let delegate = gameScene as? SKPhysicsContactDelegate {
delegate.didBeginContact?()
}
Or a one liner:
(gameScene as? SKPhysicsContactDelegate)?.didBeginContact?()
Notice the ?
after the method name in the call? It's because that method is optional and it won't get called if the object doesn't implement that method. And the if let
branch won't get executed if the object doesn't conforms to SKPhysicsContactDeletegate
protocol.
Check method existence without call
To check the existence of the method itself before calling, just omit the method call to get a reference to that methodand check it like any other variable:
if let method = (gameScene as? SKPhysicsContactDelegate)?.didBeginContact {
print("gameScene conforms to SKPhysicsContactDelegate and implements didBeginContact")
// Call it later whenever you want
method()
}
If you don't need to call it later, just check for nil
:
if (gameScene as? SKPhysicsContactDelegate)?.didBeginContact != nil {
print("gameScene conforms to SKPhysicsContactDelegate and implements didBeginContact")
}
Check for static methods
Checking for optional static
methods uses the same approach, but requires the class object instead of an instance of the class:
if (GameScene.self as? OptionalProtocol.Type)?.staticMethod != nil {
print("gameScene conforms to OptionalProtocol and implements staticMethod")
}
Notice GameScene.self
for obtaining the object type and <protocol>.Type
to cast to the protocol class instead of a protocol instance.
Full sample
Attached full sample for Playgrounds, Swift script or any online Swift compiler:
import Foundation
@objc protocol OptionalProtocol {
optional func instanceMethod()
optional static func staticMethod()
}
class Nothing {}
class Something: OptionalProtocol {}
class Bar: NSObject, OptionalProtocol {
func instanceMethod() {
print("Instance method")
}
}
class Foo: NSObject, OptionalProtocol {
static func staticMethod() {
print("Static method")
}
}
// Cast instances to 'Any' and classes to 'AnyClass'
let nothing: Any = Nothing()
let nothingClass: AnyClass = Nothing.self
let something: Any = Something()
let somethingClass: AnyClass = Something.self
let bar: Any = Bar()
let barClass: AnyClass = Bar.self
let foo: Any = Foo()
let fooClass: AnyClass = Foo.self
nothing is OptionalProtocol // false
(nothing as? OptionalProtocol)?.instanceMethod != nil // false
(nothing as? OptionalProtocol)?.instanceMethod?() // Does nothing
(nothingClass as? OptionalProtocol.Type)?.staticMethod != nil // false
(nothingClass as? OptionalProtocol.Type)?.staticMethod?() != nil // Does nothing
something is OptionalProtocol // true
(something as? OptionalProtocol)?.instanceMethod != nil // false
(something as? OptionalProtocol)?.instanceMethod?() // Does nothing
(somethingClass as? OptionalProtocol.Type)?.staticMethod != nil // false
(somethingClass as? OptionalProtocol.Type)?.staticMethod?() != nil // Does nothing
bar is OptionalProtocol // true
(bar as? OptionalProtocol)?.instanceMethod != nil // true
(bar as? OptionalProtocol)?.instanceMethod?() // Prints 'Instance method'
(barClass as? OptionalProtocol.Type)?.staticMethod != nil // false
(barClass as? OptionalProtocol.Type)?.staticMethod?() != nil // Does nothing
foo is OptionalProtocol // true
(foo as? OptionalProtocol)?.instanceMethod != nil // false
(foo as? OptionalProtocol)?.instanceMethod?() // Does nothing
(fooClass as? OptionalProtocol.Type)?.staticMethod != nil // true
(fooClass as? OptionalProtocol.Type)?.staticMethod?() != nil // Prints 'Static method'
iOS11 Swift 4 - how to check if Swift class conforms to protocol defined in Objective-C?
[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))
Objective-C Runtime: best way to check if class conforms to protocol?
According to the docs,
[MyClass conformsToProtocol:@protocol(MyProtocol)];
should work.
How do I determine what protocols a class conforms to in swift?
I don't believe you can do it without leaning on the Objective-C runtime. Import ObjectiveC
and use the class_copyProtocolList()
function.
Related Topics
Implementing a Function with a Default Parameter Defined in a Protocol
Sprite Kit Physicsbody.Resting Behavior
How to Detect Absent Network Connection When Setting Firestore Document
Higher Order Function: "Cannot Invoke 'Map' with an Argument List of Type '((_) -> _)'"
Creating a Countableclosedrange<Character>
Non-Strong References Not Working in Playground
Why Does Swift Playground Shows Wrong Number of Executions
How to Make Physics Bodies Stick to Nodes Anchor Points
What Does "Get" Mean in a Protocol's Property Declaration
Declaration Is Only Valid at File Scope (Extension)
Unsaferawpointer Assumingmemorybound VS. Bindmemory
How to Get the Height of a Uilabel in Swift
Anonymous Closure Argument Not Contained in a Closure
How to Filter Characters from a String in Swift 4