Check If Class Conforms to Protocol

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



Leave a reply



Submit