Dictionary reflection


Reflection and UnWrapping now has Dictionary support

Swift example:

let temp:Temp = Temp([0:"test",3:"testing",5:"more testing"])//create a dict
let xml: XML = Reflection.toXML(temp) //reflect the dict to xml
Swift.print(xml.XMLString)//print the xml

let newInstance: Temp = Temp.unWrap(xml)!//unwrap the xml to dict
newInstance.someDict.forEach{
    Swift.print("key: \($0.0) value: \($0.1)")//print key,value
}

class Temp {
    var someDict: [Int:String]
    init(_ someDict: [Int:String]){
        self.someDict = someDict
    }
}
extension Temp: UnWrappable{
    static func unWrap<T>(xml:XML) -> T? {
        let someDict:[Int:String] = unWrap(xml,"someDict")
        return Temp(someDict) as? T
    }
}

XML output:

<Temp>
	<someDict type="Dictionary">
		<item>
			<key type="Int">5</key>
			<value type="String">more testing</value>
		</item>
		<item>
			<key type="Int">0</key>
			<value type="String">test</value>
		</item>
		<item>
			<key type="Int">3</key>
			<value type="String">testing</value>
		</item>
	</someDict>
</Temp>

Array with Dictionary reflection:

let temp:Temp = Temp()
let xml:XML = Reflection.toXML(temp)
Swift.print("xml.xmlString: " + "\(xml.xmlString)")
class Temp{
    let temp:[[String:String]] = [["a":"b"],["1":"2"]]
}
<Temp>
	<temp type="Array">
		<item type="Dictionary">
			<item>
				<key type="String">a</key>
				<value type="String">b</value>
			</item>
		</item>
		<item type="Dictionary">
			<item>
				<key type="String">1</key>
				<value type="String">2</value>
			</item>
		</item>
	</temp>
</Temp>

Note:

Storing key and value in separate nodes is important because key can have different types and value can have nested nodes. Aka complex content. As can key when I think about it, as long as it extends the Hashable protocol.

Here is my reflection library in swift: ReflectionLib

Useful extension

import Foundation

internal class Reflection {
   /**
    * Creates dictionary of struct
    * - Parameter instance: instance of struct
    * - Returns: dictionary with key value
    */
   internal static func dict<T>(instance: T) -> [String: Any] {
      let mirror = Mirror(reflecting: instance)
      let keysWithValues = mirror.children.compactMap { (label: String?, value: Any) -> (String, Any)? in
         guard let label = label else { return nil }
         return (label, value)
      }
      return Dictionary(uniqueKeysWithValues: keysWithValues)
   }
}