Edwin Vermeer Edwin Vermeer - 5 days ago 4x
Swift Question

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
instead of

When I try the same for the friends property my goal is that it outputs something like:

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
or an

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
I can then get the parts between <> and then create an instance for that using NSClassFromString.


String(reflecting: type(of: theValue))

update by Edwin Vermeer: For the required conversion to the internal string representation i now have the following function (still in draft)

public class func convertToInternalSwiftRepresentation(type: String) -> String {
    if type.components(separatedBy: "<").count > 1 {
        // Remove the Array or Set prefix
        let prefix = type.components(separatedBy: "<") [0] + "<"
        var subtype = type.substring(from: prefix.endIndex)
        subtype = subtype.substring(to: subtype.characters.index(before: subtype.endIndex))
        return prefix + convertToInternalSwiftRepresentation(type: subtype) + ">"

    if type.contains(".") {
        var parts = type.components(separatedBy: ".")
        if parts.count == 2 {
            return parts[1]
        let c = String(repeating:"C", count: parts.count - 1)
        var rv = "_Tt\(c)\(parts[0].characters.count)\(parts[0])"
        parts.remove(at: 0)
        for part in parts {
            rv = "\(rv)\(part.characters.count)\(part)"
        return rv
    return type