0

I'm trying to compare two Any.Type. What I want to check is whether some type is equal OR inherits from that type.

Eg. UIView type is UIView.Type but it also inherits from NSObject.Type. I'm having problems to check the second one. Is it possible with Swift?

Exmaple:

class Object: NSObject {
    var name: String = "aloha"
}

class Other {
    var obj: Object?
}


let key = \Other.obj
let keyType = type(of: key)

keyType.valueType == Object?.self // true
keyType.valueType == NSObject.self // false - how can I make it true?

Edit 1:

My final goal is to have a generic VC to edit any (CoreData) object. I want to display different cells based on var's types. I find a different way for achieving what I described above (I hope - the better way). I'm still strugling though with one issue here. Although I can finally find out object's type, I want to check if that type conforms to my protocol, and if yes - call its methods. Sample code will probably explain it better:

protocol MyProtocol: class {
    static func someIdentifier() -> String
}

class Object: NSObject, MyProtocol {
    var name: String = "aloha"

    static func someIdentifier() -> String {
        return "This is it!"
    }
}

class Other: NSObject {
    var obj: Object?

}


let key = \Other.obj
let keyType = type(of: key)

let other = Other()
let value: Any? = other[keyPath: key]

if let object = value as? NSObject? {
    if let protocolObject = object as? MyProtocol {
        print("Yey!") // Can't get here :< What should I do to be able to call methods of MyProtocol?
        // protocolObject.myIdentifier() // :< How?
    }
}
msmialko
  • 1,439
  • 2
  • 20
  • 35
  • Please post your actual code. The code you have posted doesn't even compile. – Leo Dabus Jan 06 '18 at 16:38
  • 1
    Looks like it should be `let key = \Other.obj`. – rmaddy Jan 06 '18 at 16:43
  • 2
    What's the actual problem you're trying to solve here? There's almost certainly a better solution that doesn't involve comparing metatypes. That being said, you'd want to say `is NSObject.Type` instead of `== NSObject.self`, though that won't work directly with `keyType.valueType`, as its a metatype of an optional, so you'll need to use something like the `wrappedTypeFromOptionalType(_:)` function from https://stackoverflow.com/a/47860339/2976878, or `seeThroughOptionalType(_:)` function from https://stackoverflow.com/a/42753986/2976878. But as I said, you probably don't need this. – Hamish Jan 06 '18 at 16:59
  • I've edited a question description with more details :) – msmialko Jan 06 '18 at 18:59

1 Answers1

0

You Can't get here because value aka obj is nil.

Please look at this. I changed someIdentifier() to an instance method and assigned an Object instance to obj. Further I removed the unnecessary type annotation let value: Any? because a type cast from Object to Any makes it worse and consolidated the optional down cast if let object = value as NSObject? by removing the second question mark.

protocol MyProtocol: class {
    func someIdentifier() -> String
}

class Object: NSObject, MyProtocol {
    var name: String = "aloha"

    func someIdentifier() -> String {
        return "This is it!"
    }
}

class Other: NSObject {
    var obj: Object?
}


let key = \Other.obj
let keyType = type(of: key)

let other = Other()
other.obj = Object()
let value = other[keyPath: key]

if let object = value as NSObject? {
    if let protocolObject = object as? MyProtocol {
        print(protocolObject.someIdentifier()) // This is it!
    }
}
vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thanks @vadian but I deliberetaly was using `Static` method in the protocol because `obj` can be `nil` in many cases and I still want to call that protocol method on its type. – msmialko Jan 06 '18 at 19:43
  • You cannot call a static function on the protocol type. – vadian Jan 06 '18 at 19:49
  • I can call though `Object.someIdentifier()`. How it’s workig then? – msmialko Jan 06 '18 at 19:54
  • Yes, this is possible. But then `protocolObject` is obsolete and you could check `if object is MyProtocol { ...` – vadian Jan 06 '18 at 20:01