I am trying to get the property list of a swift class. There is a similar question here and here. I have everything working except for certain types do not get returned from class_copyPropertyList
. The ones I have tested it with so far are Int?
and enums. I have an example class below of what I am trying.
enum PKApiErrorCode: Int {
case None = 0
case InvalidSignature = 1
case MissingRequired = 2
case NotLoggedIn = 3
case InvalidApiKey = 4
case InvalidLogin = 5
case RegisterFailed = 6
}
class ApiError: Serializable {
let code: PKApiErrorCode?
let message: String?
let userMessage: String?
init(error: JSONDictionary) {
code = error["errorCode"] >>> { (object: JSON) -> PKApiErrorCode? in
if let c = object >>> JSONInt {
return PKApiErrorCode.fromRaw(c)
}
return nil
}
message = error["message"] >>> JSONString
userMessage = error["userMessage"] >>> JSONString
}
}
And the Serializable class (with some help from https://gist.github.com/turowicz/e7746a9c035356f9483d is
public class Serializable: NSObject, Printable {
override public var description: String {
return "\(self.toDictionary())"
}
}
extension Serializable {
public func toDictionary() -> NSDictionary {
var aClass : AnyClass? = self.dynamicType
var propertiesCount : CUnsignedInt = 0
let propertiesInAClass : UnsafeMutablePointer<objc_property_t> = class_copyPropertyList(aClass, &propertiesCount)
var propertiesDictionary : NSMutableDictionary = NSMutableDictionary()
for var i = 0; i < Int(propertiesCount); i++ {
var property = propertiesInAClass[i]
var propName = NSString(CString: property_getName(property), encoding: NSUTF8StringEncoding)
var propType = property_getAttributes(property)
var propValue : AnyObject! = self.valueForKey(propName);
if propValue is Serializable {
propertiesDictionary.setValue((propValue as Serializable).toDictionary(), forKey: propName)
} else if propValue is Array<Serializable> {
var subArray = Array<NSDictionary>()
for item in (propValue as Array<Serializable>) {
subArray.append(item.toDictionary())
}
propertiesDictionary.setValue(subArray, forKey: propName)
} else if propValue is NSData {
propertiesDictionary.setValue((propValue as NSData).base64EncodedStringWithOptions(nil), forKey: propName)
} else if propValue is Bool {
propertiesDictionary.setValue((propValue as Bool).boolValue, forKey: propName)
} else if propValue is NSDate {
var date = propValue as NSDate
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "Z"
var dateString = NSString(format: "/Date(%.0f000%@)/", date.timeIntervalSince1970, dateFormatter.stringFromDate(date))
propertiesDictionary.setValue(dateString, forKey: propName)
} else {
propertiesDictionary.setValue(propValue, forKey: propName)
}
}
return propertiesDictionary
}
public func toJSON() -> NSData! {
var dictionary = self.toDictionary()
var err: NSError?
return NSJSONSerialization.dataWithJSONObject(dictionary, options:NSJSONWritingOptions(0), error: &err)
}
public func toJSONString() -> NSString! {
return NSString(data: self.toJSON(), encoding: NSUTF8StringEncoding)
}
}
The String seem to only appear if the Optionals are valid values and the code
never appears on the object if it is an enum or Int unless the Int has a default value.
Thanks for any advice I can get for getting all properties of a class no matter what they are.