I'm trying to check if an object is of a given type and I'm getting an error:
'expectedClass' is not a type
My code below.
func testInputValue(inputValue: AnyObject, isKindOfClass expectedClass: AnyClass) throws {
guard let object = inputValue as? expectedClass else {
// Throw an error
let userInfo = [NSLocalizedDescriptionKey: "Expected an inputValue of type \(expectedClass), but got a \(inputValue.dynamicType)"]
throw NSError(domain: RKValueTransformersErrorDomain, code: Int(RKValueTransformationError.UntransformableInputValue.rawValue), userInfo: userInfo)
}
}
I'm trying to figure out what can be wrong here.
You should be able to do this with generics:
func testInputValue<T>(inputValue: AnyObject, isKindOfClass expectedClass: T.Type) throws {
guard let object = inputValue as? T else {
...
}
}
You should not do class comparisons with ==
as suggested in one of the other answers, unless you specifically want to test if the type of the object tested should exactly match the expected class and it is not allowed to be a subclass of the tested class.
You can use the instance method isKindOfClass
to accomplish this, taking subclassing into account. See below for a code example.
NOTE: You may be surprised that this works on a pure Swift class type, given an instance method with the same name exists in NSObject
/ NSObjectProtocol
. It does indeed work in pure Swift (as shown with the example code below – tested with Xcode 7.3, Swift 2.2.1), with no @objc
types involved, as long as you import Foundation. I am presuming based on this that this instance method is added as an extension method in Foundation to all class types.
import Foundation
class A { }
class B { }
class C: B { }
enum ValueTestError: ErrorType {
case UnexpectedClass(AnyClass)
}
func testInputValue(inputObj:AnyObject, isKindOfClass expectedClass:AnyClass) throws {
guard inputObj.isKindOfClass(expectedClass) else {
throw ValueTestError.UnexpectedClass(inputObj.dynamicType)
}
}
let a = A()
let b = B()
let c = C()
do {
try testInputValue(c, isKindOfClass: B.self)
} catch {
print("This does not get printed as c is of type B (C is subclass of B).")
}
do {
try testInputValue(a, isKindOfClass: B.self)
} catch {
print("This gets printed as a is not of type B.")
}
Also, importantly although isKindOfClass
is available as an instance method on AnyObject, trying to call it on an arbitrary Swift class typed object will only work if you first cast that object to AnyObject (which will always of course succeed). Example code illustrating this point is presented below, and there's more on this question over here.
import Foundation
class A {}
let a = A()
// the following compiles and returns 'true'
(a as AnyObject).isKindOfClass(A.self)
// the following fails to compile with "Value of type 'A' has no member 'isKindOfClass'"
a.isKindOfClass(A.self)
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