diff --git a/ObjectiveKit.xcodeproj/project.pbxproj b/ObjectiveKit.xcodeproj/project.pbxproj index a6fb358..671e7af 100644 --- a/ObjectiveKit.xcodeproj/project.pbxproj +++ b/ObjectiveKit.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 344C27861DD5CDCF008AA223 /* ObjectiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 344C27781DD5CDCF008AA223 /* ObjectiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 344C27901DD5CFAB008AA223 /* ObjectiveClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 344C278F1DD5CFAB008AA223 /* ObjectiveClass.swift */; }; 344C27941DD6F4E1008AA223 /* RuntimeClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 344C27931DD6F4E1008AA223 /* RuntimeClass.swift */; }; + D7D1F6F71E4BAE4200C6E22E /* Optional+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D1F6F61E4BAE4200C6E22E /* Optional+Extensions.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -35,6 +36,7 @@ 344C27851DD5CDCF008AA223 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 344C278F1DD5CFAB008AA223 /* ObjectiveClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectiveClass.swift; sourceTree = ""; }; 344C27931DD6F4E1008AA223 /* RuntimeClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuntimeClass.swift; sourceTree = ""; }; + D7D1F6F61E4BAE4200C6E22E /* Optional+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Optional+Extensions.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -82,6 +84,7 @@ 344C27931DD6F4E1008AA223 /* RuntimeClass.swift */, 344553051DDA6C1B007852A1 /* RuntimeModification.swift */, 344C27791DD5CDCF008AA223 /* Info.plist */, + D7D1F6F61E4BAE4200C6E22E /* Optional+Extensions.swift */, ); path = ObjectiveKit; sourceTree = ""; @@ -174,6 +177,7 @@ hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 344C276B1DD5CDCF008AA223; productRefGroup = 344C27761DD5CDCF008AA223 /* Products */; @@ -209,6 +213,7 @@ buildActionMask = 2147483647; files = ( 344C27901DD5CFAB008AA223 /* ObjectiveClass.swift in Sources */, + D7D1F6F71E4BAE4200C6E22E /* Optional+Extensions.swift in Sources */, 344553061DDA6C1B007852A1 /* RuntimeModification.swift in Sources */, 344C27941DD6F4E1008AA223 /* RuntimeClass.swift in Sources */, ); diff --git a/ObjectiveKit/ObjectiveClass.swift b/ObjectiveKit/ObjectiveClass.swift index a9cd787..0de9f02 100644 --- a/ObjectiveKit/ObjectiveClass.swift +++ b/ObjectiveKit/ObjectiveClass.swift @@ -12,6 +12,8 @@ typealias ImplementationBlock = @convention(block) () -> Void /// An object that allows you to introspect and modify classes through the ObjC runtime. public class ObjectiveClass : ObjectiveKitRuntimeModification { + + private typealias RuntimeCopyingGetter = (AnyClass?, UnsafeMutablePointer?) -> UnsafeMutablePointer! public var internalClass: AnyClass @@ -28,81 +30,61 @@ public class ObjectiveClass : ObjectiveKitRuntimeModification { /// /// - Returns: An array of instance variables. public var ivars: [String] { - get { - var count: CUnsignedInt = 0 - var ivars = [String]() - let ivarList = class_copyIvarList(internalClass, &count) - for i in (0..( + with copyingGetter: RuntimeCopyingGetter, + transform: (Type) -> Result? + ) + -> [Result] + { + var cCount: CUnsignedInt = 0 + + let entities = copyingGetter(self.internalClass, &cCount) + let count = Int(exactly: cCount) ?? 0 + + defer { entities?.deallocate(capacity: count) } + + return UnsafeMutableBufferPointer(start: entities, count: count) + .flatMap(identity) + .flatMap(transform) + } + + private func runtimeStrings( + with copyingGetter: RuntimeCopyingGetter, + transform: (Type!) -> UnsafePointer! + ) + -> [String] + { + return self.runtimeEntities(with: copyingGetter) { + pure(transform($0)).map(String.init(cString:)) } } - } - - diff --git a/ObjectiveKit/Optional+Extensions.swift b/ObjectiveKit/Optional+Extensions.swift new file mode 100644 index 0000000..06b5852 --- /dev/null +++ b/ObjectiveKit/Optional+Extensions.swift @@ -0,0 +1,17 @@ +// +// Optional+Extensions.swift +// ObjectiveKit +// +// Created by Oleksa 'trimm' Korin on 2/8/17. +// Copyright © 2017 Roy Marmelstein. All rights reserved. +// + +/// Wraps value in optional +public func pure(_ value: T) -> T? { + return value +} + +/// Returns the value passed as the parameter +public func identity(_ value: T) -> T { + return value +}