Skip to content

Commit

Permalink
Support for structs like CGPoint and CGRect
Browse files Browse the repository at this point in the history
  • Loading branch information
evermeer committed Apr 5, 2016
1 parent e83cffa commit 0850ce6
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 19 deletions.
2 changes: 1 addition & 1 deletion EVReflection.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Pod::Spec.new do |s|
#

s.name = "EVReflection"
s.version = "2.22.2"
s.version = "2.23.0"
s.summary = "iOS: Swift helper library with reflection functions"
s.description = "Swift helper library with reflection functions including support for NSCoding, Printable, Hashable, Equatable and JSON"
s.homepage = "https://github.com/evermeer/EVReflection"
Expand Down
10 changes: 0 additions & 10 deletions EVReflection/EVReflectionTests/EVReflectionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -302,16 +302,6 @@ class EVReflectionTests: XCTestCase {
print(myObject.toJsonString())
}

func testStruct() {
//TODO: Fix structs
let json = X().toJsonString()
print("json = \(json)")
}
}

class X: EVObject {
var y:String = "the y"
var c:CGPoint = CGPointMake(2,3)
}


Expand Down
21 changes: 19 additions & 2 deletions EVReflection/EVReflectionTests/EVReflectionWorkaroundsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ class EVReflectionWorkaroundsTests: XCTestCase {
XCTAssertEqual(doc.dict["firstkey"]?.field, "5", "First sentence should have id 5")
XCTAssertEqual(doc.dict["secondkey"]?.field, "35", "Second sentence should have id 35")
}

func testStruct() {
let event = WorkaroundObject()
event.structType = CGPointMake(2,3)

let json = event.toJsonString()
print("json = \(json)")

let newEvent = WorkaroundObject(json:json)
XCTAssertEqual(newEvent.structType.x, 2, "The location x should have been 2")
XCTAssertEqual(newEvent.structType.y, 3, "The location y should have been 3")
}
}


Expand All @@ -83,6 +95,7 @@ class WorkaroundObject: EVObject, EVArrayConvertable, EVDictionaryConvertable {
var enumType: StatusType = .OK
var list: [WorkaroundObject?] = [WorkaroundObject?]()
var dict: [String: SubObject] = [:]
var structType: CGPoint = CGPointMake(0,0)

// Handling the setting of non key-value coding compliant properties
override func setValue(value: AnyObject!, forUndefinedKey key: String) {
Expand All @@ -109,6 +122,12 @@ class WorkaroundObject: EVObject, EVArrayConvertable, EVDictionaryConvertable {
self.dict[key as! String] = (value as! SubObject)
}
}
case "structType":
if let dict = value as? NSDictionary {
if let x = dict["x"] as? NSNumber, let y = dict["y"] as? NSNumber {
structType = CGPointMake(CGFloat(x), CGFloat(y))
}
}
default:
print("---> setValue for key '\(key)' should be handled.")
}
Expand Down Expand Up @@ -142,5 +161,3 @@ class WorkaroundObject: EVObject, EVArrayConvertable, EVDictionaryConvertable {





2 changes: 1 addition & 1 deletion EVReflection/EVReflectionTests/WorkaroundEnumTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class EVReflectionTests2: XCTestCase {
print("\(test)")
var comments = EVReflection.arrayFromJson(Comment(), json: test)
var comments2 = [Comment](json: test)

print(comments[0].testuserinfo?.uid)
print(comments2[0].testuserinfo?.uid)
}
Expand Down
27 changes: 22 additions & 5 deletions EVReflection/pod/EVReflection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -517,11 +517,12 @@ final public class EVReflection {
public class func valueForAny(parentObject:Any? = nil, key:String? = nil, anyValue: Any) -> (value: AnyObject, type: String, isObject: Bool) {
var theValue = anyValue
var valueType = "EVObject"
let mi: Mirror = Mirror(reflecting: theValue)
var mi: Mirror = Mirror(reflecting: theValue)

if mi.displayStyle == .Optional {
if mi.children.count == 1 {
theValue = mi.children.first!.value
mi = Mirror(reflecting: theValue)
if("\(theValue)".hasPrefix("_TtC")) {
valueType = "\(theValue)".componentsSeparatedByString(" ")[0]
} else {
Expand All @@ -533,7 +534,9 @@ final public class EVReflection {
subtype = subtype.substringToIndex(subtype.endIndex.predecessor())
return (NSNull(), subtype, false)
}
} else if mi.displayStyle == .Enum {
}

if mi.displayStyle == .Enum {
valueType = "\(theValue.dynamicType)"
if let value = theValue as? EVRawString {
return (value.rawValue, "\(mi.subjectType)", false)
Expand Down Expand Up @@ -565,7 +568,10 @@ final public class EVReflection {
return (convertedValue, valueType, false)
}
}
assert(true, "WARNING: An object with a property of type Dictionary (not NSDictionary) should implement the EVDictionaryConvertable protocol.")
NSLog("Converting a struct to a dictionary for: \(theValue)")
let structAsDict = convertStructureToDictionary(theValue)
return (structAsDict, "Struct", false)
//assert(true, "WARNING: An object with a property of type Dictionary (not NSDictionary) should implement the EVDictionaryConvertable protocol.")
} else {
valueType = "\(mi.subjectType)"
}
Expand Down Expand Up @@ -614,6 +620,13 @@ final public class EVReflection {
}
}

private static func convertStructureToDictionary(theValue: Any) -> NSDictionary {
let reflected = Mirror(reflecting: theValue)
let (addProperties, _) = reflectedSub(theValue, reflected: reflected, performKeyCleanup: false)
return addProperties
}


/**
Try to set a value of a property with automatic String to and from Number conversion

Expand Down Expand Up @@ -664,7 +677,11 @@ final public class EVReflection {
}
}
}
anyObject.setValue(value!, forKey: key)
if typeInObject == "Struct" {
anyObject.setValue(value!, forUndefinedKey: key)
} else {
anyObject.setValue(value!, forKey: key)
}
}
}

Expand Down Expand Up @@ -805,7 +822,7 @@ final public class EVReflection {
dictValue = org.convertDictionary(key, dict: dict)
} else if type != "NSDictionary" && dictValue as? NSDictionary != nil {
// Sub object
dictValue = dictToObject(type, original:original ,dict: dictValue as! NSDictionary)
dictValue = (dictToObject(type, original:original ,dict: dictValue as! NSDictionary) ?? dictValue)
} else if type.rangeOfString("<NSDictionary>") == nil && dictValue as? [NSDictionary] != nil {
// Array of objects
dictValue = dictArrayToObjectArray(type, array: dictValue as! [NSDictionary]) as [NSObject]
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,13 +235,15 @@ EVReflection is trying to handle all types. With some types there are limitation
- properties based on an enum
- an Array of nullable objects like [MyObject?]
- generic properties like var myVal:T = T()
- structs like CGRect or CGPoint

For all these issues there are workarounds. The easiest workaround is just using a difrent type like:

- Instead of an Int? you could use NSNumber?
- Instead of [MyObject?] use [MyObject]
- Instead of 'var status: StatysType' use 'var status:Int' and save the rawValue
- Instead of a generic property use a specific property that can hold the data (a dictionary?)
- Instead of using a struct, create your own object model for that struct

If you want to keep on using the same type, You can override the setValue forUndefinedKey in the object itself. See WorkaroundsTests.swift and WorkaroundSwiftGenericsTests.swift to see the workaround for all these types in action.

Expand Down

0 comments on commit 0850ce6

Please sign in to comment.