Skip to content

Commit

Permalink
Giving support for superclasses
Browse files Browse the repository at this point in the history
  • Loading branch information
Sajjon committed Oct 5, 2016
1 parent 3554482 commit bfd4087
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 18 deletions.
9 changes: 5 additions & 4 deletions SwiftReflection.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
65F8AC271D78824F00B44DE8 /* SwiftReflectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F8AC261D78824F00B44DE8 /* SwiftReflectionTests.swift */; };
65F8AC291D78824F00B44DE8 /* SwiftReflection.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 653598FF1D787F6500B411D1 /* SwiftReflection.framework */; };
65F8AC311D78827F00B44DE8 /* Book.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F8AC301D78827F00B44DE8 /* Book.swift */; };
65F8AC331D7882E300B44DE8 /* PrimitiveDataTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F8AC321D7882E300B44DE8 /* PrimitiveDataTypes.swift */; };
65F8AC331D7882E300B44DE8 /* ValueTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F8AC321D7882E300B44DE8 /* ValueTypes.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -34,7 +34,7 @@
65F8AC261D78824F00B44DE8 /* SwiftReflectionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftReflectionTests.swift; sourceTree = "<group>"; };
65F8AC281D78824F00B44DE8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
65F8AC301D78827F00B44DE8 /* Book.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Book.swift; sourceTree = "<group>"; };
65F8AC321D7882E300B44DE8 /* PrimitiveDataTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrimitiveDataTypes.swift; sourceTree = "<group>"; };
65F8AC321D7882E300B44DE8 /* ValueTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValueTypes.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -98,7 +98,7 @@
isa = PBXGroup;
children = (
65F8AC301D78827F00B44DE8 /* Book.swift */,
65F8AC321D7882E300B44DE8 /* PrimitiveDataTypes.swift */,
65F8AC321D7882E300B44DE8 /* ValueTypes.swift */,
);
path = TestClasses;
sourceTree = "<group>";
Expand Down Expand Up @@ -222,7 +222,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
65F8AC331D7882E300B44DE8 /* PrimitiveDataTypes.swift in Sources */,
65F8AC331D7882E300B44DE8 /* ValueTypes.swift in Sources */,
65F8AC311D78827F00B44DE8 /* Book.swift in Sources */,
65F8AC271D78824F00B44DE8 /* SwiftReflectionTests.swift in Sources */,
);
Expand Down Expand Up @@ -427,6 +427,7 @@
65F8AC2D1D78824F00B44DE8 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
Expand Down
40 changes: 28 additions & 12 deletions SwiftReflection/SwiftReflection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,34 @@ import ObjectiveC.runtime
This tool can find the name and type of properties of type NSObject, e.g. NSString (or just "String" with Swift 3 syntax), NSDate (or just "NSDate" with Swift 3 syntax), NSNumber etc.
It also works with optionals and implicit optionals for said types, e.g. String?, String!, Date!, Date? etc...

This tool can also find name and type of "primitive data types" such as Bool, Int, Int32, _HOWEVER_ it does not work if said primitive have optional type, e.g. Int? <--- DOES NOT WORK
This tool can also find name and type of "value type" such as Bool, Int, Int32, _HOWEVER_ it does not work if said value type is an optional, e.g. Int? <--- DOES NOT WORK
*/


public func getTypesOfProperties(in clazz: NSObject.Type) -> Dictionary<String, Any>? {
public func getTypesOfProperties(in clazz: NSObject.Type, includeSuperclass: Bool = false) -> Dictionary<String, Any>? {
let types: Dictionary<String, Any> = [:]
return getTypesOfProperties(in: clazz, types: types, includeSuperclass: includeSuperclass)
}

public func getTypesOfProperties(in clazz: NSObject.Type, types: Dictionary<String, Any>, includeSuperclass: Bool) -> Dictionary<String, Any>? {
var count = UInt32()
guard let properties = class_copyPropertyList(clazz, &count) else { return nil }
var types: Dictionary<String, Any> = [:]
var types = types
for i in 0..<Int(count) {
guard let property: objc_property_t = properties[i], let name = getNameOf(property: property) else { continue }
guard
let property: objc_property_t = properties[i],
let name = getNameOf(property: property)
else { continue }
let type = getTypeOf(property: property)
types[name] = type
}
free(properties)
return types

if includeSuperclass, let superclazz = clazz.superclass() as? NSObject.Type, superclazz != NSObject.self {
return getTypesOfProperties(in: superclazz, types: types, includeSuperclass: true)
} else {
return types
}
}

public func getTypesOfProperties(ofObject object: NSObject) -> Dictionary<String, Any>? {
Expand Down Expand Up @@ -61,8 +74,8 @@ public func isProperty(named propertyName: String, ofType targetType: Any, in cl
}

fileprivate func ==(rhs: Any, lhs: Any) -> Bool {
var rhsType: String = "\(rhs)".withoutOptional
var lhsType: String = "\(lhs)".withoutOptional
let rhsType: String = "\(rhs)".withoutOptional
let lhsType: String = "\(lhs)".withoutOptional
let same = rhsType == lhsType
return same
}
Expand All @@ -86,23 +99,26 @@ fileprivate func getTypeOf(property: objc_property_t) -> Any {
guard let attributesAsNSString: NSString = NSString(utf8String: property_getAttributes(property)) else { return Any.self }
let attributes = attributesAsNSString as String
let slices = attributes.components(separatedBy: "\"")
guard slices.count > 1 else { return getPrimitiveDataType(withAttributes: attributes) }
guard slices.count > 1 else { return valueType(withAttributes: attributes) }
let objectClassName = slices[1]
let objectClass = NSClassFromString(objectClassName) as! NSObject.Type
return objectClass
}

fileprivate func getPrimitiveDataType(withAttributes attributes: String) -> Any {
guard let letter = attributes.substring(from: 1, to: 2), let type = primitiveDataTypes[letter] else { return Any.self }

fileprivate func valueType(withAttributes attributes: String) -> Any {
guard let letter = attributes.substring(from: 1, to: 2), let type = valueTypesMap[letter] else { return Any.self }
return type
}

fileprivate func getNameOf(property: objc_property_t) -> String? {
guard let name: NSString = NSString(utf8String: property_getName(property)) else { return nil }
guard
let name: NSString = NSString(utf8String: property_getName(property))
else { return nil }
return name as String
}

fileprivate let primitiveDataTypes: Dictionary<String, Any> = [
fileprivate let valueTypesMap: Dictionary<String, Any> = [
"c" : Int8.self,
"s" : Int16.self,
"i" : Int32.self,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// PrimitiveDataTypes.swift
// ValueTypes.swift
// SwiftReflection
//
// Created by Cyon Alexander (Ext. Netlight) on 01/09/16.
Expand All @@ -8,7 +8,7 @@

import Foundation

class PrimitiveDataTypes: NSObject {
class ValueTypes: NSObject {
var int8: Int8 = 1
var int16: Int16 = 1
var int32: Int32 = 1
Expand Down

0 comments on commit bfd4087

Please sign in to comment.