lundi 17 octobre 2016

How to get the string representation of a nested class

In my reflection library EVReflection I have the following problem when class definitions are nested (class within a class). Below is a worked out case which can be found as a unit test here and The location in the library itself where the code needs to change is Here

I need to get the Internal Swift string representation of a nested class for a property which is an array of that nested class.

Below you can see a unit test where I am able to get the correct type for the property company that is an other object. It will output _TtCC22EVReflection_iOS_Tests13TestIssue114b10Company114 instead of Company114

When I try the same for the friends property my goal is that it outputs something like: Swift.Array<_TtCC22EVReflection_iOS_Tests13TestIssue114b7User114> What do I have to do to get that?

As you can see in the test I have various assignments to the value valueType. None of these assignments work. I am only able to get an Array<User114> or an Swift._EmptyArrayStorage.

As you also can see in the test is that if i set a breakpoint and do a po in the outut window I am able to get the correct output. So what code will accomplish the same in my code?

class TestIssue114b: XCTestCase {
    class User114: EVObject {
        var company: Company114 = Company114()
        var friends: [User114] = []
    }

    class Company114: EVObject {
        var name: String = ""
        var address: String?
    }

    func testIssueNestedObjects() {
        let x = User114()
        print("type 1 = \(NSStringFromClass(type(of: x.company)))") // output = type 2 = _TtCC22EVReflection_iOS_Tests13TestIssue114b10Company114
        print("type 2 = \(testIssueNestedObjects(x.friends))")

    }

    func testIssueNestedObjects(_ theValue: Any) -> String {
        var valueType = ""
        let mi = Mirror(reflecting: theValue)
        valueType = NSStringFromClass(type(of: (theValue as! [NSObject]).getTypeInstance() as NSObject))  //  NSObject
        valueType = "\(type(of: theValue))"   // Array<User114>
        valueType = "\(mi.subjectType)"      // Array<User114>
        valueType = ObjectIdentifier(mi.subjectType).debugDescription //"ObjectIdentifier(0x0000000118b4a0d8)"
        valueType = (theValue as AnyObject).debugDescription      // <Swift._EmptyArrayStorage 0x10d860b50>
        valueType = NSStringFromClass(type(of: theValue as AnyObject)) // Swift._EmptyArrayStorage
        // set breakpont en enter this in output window: (lldb) po type(of: theValue)
        // Ouput will be: Swift.Array<EVReflection_iOS_Tests.TestIssue114b.User114>
        return valueType
    }
}

Background info: Actually the end goal is that I have to be able to create instances of the object that I can add to the array. Since the array property is only available as a result from a Mirror command the variable will be of type Any. I do have an extension for arrays in place that will return a new array element. however I am only able to get that when the Any is casted to Array and because of that my extension will return an NSObject. So I would like to get a string like Swift.Array<_TtCC22EVReflection_iOS_Tests13TestIssue114b7User114> I can then get the parts between <> and then create an instance for that using NSClassFromString.





Aucun commentaire:

Enregistrer un commentaire