0

While it's possible to get a list of properties from an instance: it requires an instance which is troublesome if the Type isn't trivial and doesn't have a straightforward .init(). Similarly, can't we test the existence of a nested type?

struct SomeStruct: Codable {
    var x: Int
    var y: Int
}
class CoolClass: Codable {
    var thing: SomeStruct
    var name: String
    enum CodingKeys: String, CodingKey {
        case name = "title", name = "stuff"
    }
}

func testA(_ type: Any.Type) {
    if type is Codable.Protocol {
        print("is Codable")
    } else {
        print("is NOT Codable")
    }
    let mirror = Mirror(reflecting: type)
    mirror.children  // << empty collection!!
}

func testB<T>(_ type: T.Type) where T: Codable {
    // test if `type` defines `CodingKeys` or if it is synthesized.
    
}

testA(SomeStruct.self)  // "is NOT Codable", can't get list of ["x", "y"]
                        // , nor can't get CodingKeys...

If there is no reflection for metatypes, my attempts at piggybacking off of Codable's CodingKeys (explicit or synthesized) have all failed. Is this possible?

  • You might be facing an [X-Y problem](https://meta.stackexchange.com/a/66378/284459). Let's start with what you are trying to accomplish to begin with, that led you to try to see if CodingKeys is synthesized or user-defined, whether you can reflect on a type, and so forth – New Dev Jan 24 '21 at 22:57
  • @NewDev: **Requirement:** Obtain a list of a type's property names without requiring an instance of said type. –  Jan 24 '21 at 23:14
  • So, that's an attempted *solution* to some original problem, which now faces its own problem. What is that original problem? It might be that the attempted solution is not needed at all – New Dev Jan 24 '21 at 23:16

1 Answers1

0

I don't know how to solve your main problem, but you are not checking correctly if type is codable. Since type is already a structure/class type (not an object), you should try to cast it from Any.Type to Codable.Type, which will only succeed if type implements Codable:

if type as? Codable.Type != nil {
    print("is Codable")
} else {
    print("is NOT Codable")
}
timbre timbre
  • 12,648
  • 10
  • 46
  • 77
  • Cool! Thank you! Not sure if this is worthy of its own question: But is the difference between both: `Codable.Type` return a type whereas `Codable.Protocol` return a metatype? –  Jan 25 '21 at 00:19
  • @user1040049 they are both metatypes. The `type as Codable.Type` refers to "Codable nature" of the `type` you provided (i.e. all properties and functions of `type` that are related to implementation of `Codable`). While `Codable.Protocol` refers to protocol itself - same as `Codable.self`. – timbre timbre Jan 25 '21 at 04:05