diff --git a/Aspects.xcodeproj/project.pbxproj b/Aspects.xcodeproj/project.pbxproj index 155a5eb..4430a8f 100644 --- a/Aspects.xcodeproj/project.pbxproj +++ b/Aspects.xcodeproj/project.pbxproj @@ -12,7 +12,8 @@ 34B986A51B1E491000DE719D /* Aspects.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B986841B1DE2BE00DE719D /* Aspects.m */; }; 34B986A61B1E491300DE719D /* Aspects.h in Headers */ = {isa = PBXBuildFile; fileRef = 34B9866C1B1DE0CE00DE719D /* Aspects.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7376F8CD1B8EA767009CAB74 /* Aspects.h in Headers */ = {isa = PBXBuildFile; fileRef = 34B9866C1B1DE0CE00DE719D /* Aspects.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7376F8D61B8EB1FA009CAB74 /* Aspects.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B986841B1DE2BE00DE719D /* Aspects.m */; settings = {ASSET_TAGS = (); }; }; + 7376F8D61B8EB1FA009CAB74 /* Aspects.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B986841B1DE2BE00DE719D /* Aspects.m */; }; + 9CDB17402293EF0A00FAC8D5 /* AspectsSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CDB173F2293EF0A00FAC8D5 /* AspectsSwift.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -23,6 +24,7 @@ 34B9868C1B1E48CD00DE719D /* Aspects.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Aspects.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7376F8C31B8EA670009CAB74 /* Aspects.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Aspects.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7376F8C71B8EA670009CAB74 /* Info-watch.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-watch.plist"; sourceTree = ""; }; + 9CDB173F2293EF0A00FAC8D5 /* AspectsSwift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AspectsSwift.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -73,6 +75,7 @@ children = ( 34B9866C1B1DE0CE00DE719D /* Aspects.h */, 34B986841B1DE2BE00DE719D /* Aspects.m */, + 9CDB173F2293EF0A00FAC8D5 /* AspectsSwift.swift */, 34B9866A1B1DE0CE00DE719D /* Supporting Files */, ); name = Aspects; @@ -182,6 +185,7 @@ TargetAttributes = { 34B986661B1DE0CE00DE719D = { CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 1000; }; 34B9868B1B1E48CD00DE719D = { CreatedOnToolsVersion = 6.3.1; @@ -240,6 +244,7 @@ buildActionMask = 2147483647; files = ( 34B986851B1DE2BE00DE719D /* Aspects.m in Sources */, + 9CDB17402293EF0A00FAC8D5 /* AspectsSwift.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -353,6 +358,7 @@ 34B9867E1B1DE0CE00DE719D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -362,12 +368,15 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = Aspects; SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; }; name = Debug; }; 34B9867F1B1DE0CE00DE719D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -377,6 +386,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = Aspects; SKIP_INSTALL = YES; + SWIFT_VERSION = 4.2; }; name = Release; }; diff --git a/AspectsSwift.swift b/AspectsSwift.swift new file mode 100644 index 0000000..023d265 --- /dev/null +++ b/AspectsSwift.swift @@ -0,0 +1,370 @@ +// +// AspectsSwift.swift +// Aspects-iOS +// +// Created by roy.cao on 2019/5/21. +// Copyright © 2019 Peter Steinberger. All rights reserved. +// + +import Foundation + +public extension NSObject { + + func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + usingBlock(aspectInfo) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 1, + let arg1 = aspectInfo.arguments()[0] as? Arg1 else { return } + usingBlock(aspectInfo, arg1) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 2, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2 else { return } + usingBlock(aspectInfo, arg1, arg2) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2, Arg3) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 3, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2, + let arg3 = aspectInfo.arguments()[2] as? Arg3 else { return } + usingBlock(aspectInfo, arg1, arg2, arg3) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2, Arg3, Arg4) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 4, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2, + let arg3 = aspectInfo.arguments()[2] as? Arg3, + let arg4 = aspectInfo.arguments()[3] as? Arg4 else { return } + usingBlock(aspectInfo, arg1, arg2, arg3, arg4) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2, Arg3, Arg4, Arg5) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 5, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2, + let arg3 = aspectInfo.arguments()[2] as? Arg3, + let arg4 = aspectInfo.arguments()[3] as? Arg4, + let arg5 = aspectInfo.arguments()[4] as? Arg5 else { + return + } + usingBlock(aspectInfo, arg1, arg2, arg3, arg4, arg5) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 6, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2, + let arg3 = aspectInfo.arguments()[2] as? Arg3, + let arg4 = aspectInfo.arguments()[3] as? Arg4, + let arg5 = aspectInfo.arguments()[4] as? Arg5, + let arg6 = aspectInfo.arguments()[5] as? Arg6 else { + return + } + usingBlock(aspectInfo, arg1, arg2, arg3, arg4, arg5, arg6) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + + func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 7, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2, + let arg3 = aspectInfo.arguments()[2] as? Arg3, + let arg4 = aspectInfo.arguments()[3] as? Arg4, + let arg5 = aspectInfo.arguments()[4] as? Arg5, + let arg6 = aspectInfo.arguments()[5] as? Arg6, + let arg7 = aspectInfo.arguments()[6] as? Arg7 else { + return + } + usingBlock(aspectInfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } +} + +public extension NSObject { + + class func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + usingBlock(aspectInfo) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + class func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 1, + let arg1 = aspectInfo.arguments()[0] as? Arg1 else { return } + usingBlock(aspectInfo, arg1) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + class func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 2, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2 else { return } + usingBlock(aspectInfo, arg1, arg2) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + class func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2, Arg3) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 3, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2, + let arg3 = aspectInfo.arguments()[2] as? Arg3 else { return } + usingBlock(aspectInfo, arg1, arg2, arg3) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + class func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2, Arg3, Arg4) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 4, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2, + let arg3 = aspectInfo.arguments()[2] as? Arg3, + let arg4 = aspectInfo.arguments()[3] as? Arg4 else { return } + usingBlock(aspectInfo, arg1, arg2, arg3, arg4) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + class func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2, Arg3, Arg4, Arg5) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 5, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2, + let arg3 = aspectInfo.arguments()[2] as? Arg3, + let arg4 = aspectInfo.arguments()[3] as? Arg4, + let arg5 = aspectInfo.arguments()[4] as? Arg5 else { + return + } + usingBlock(aspectInfo, arg1, arg2, arg3, arg4, arg5) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + class func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 6, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2, + let arg3 = aspectInfo.arguments()[2] as? Arg3, + let arg4 = aspectInfo.arguments()[3] as? Arg4, + let arg5 = aspectInfo.arguments()[4] as? Arg5, + let arg6 = aspectInfo.arguments()[5] as? Arg6 else { + return + } + usingBlock(aspectInfo, arg1, arg2, arg3, arg4, arg5, arg6) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } + + class func aspect_hook( + selector: Selector, + options: AspectOptions, + usingBlock: @escaping(AspectInfo, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) -> Void) throws + { + let wrappedBlock: @convention(block) (AspectInfo) -> Void = { aspectInfo in + guard aspectInfo.arguments()?.count == 7, + let arg1 = aspectInfo.arguments()[0] as? Arg1, + let arg2 = aspectInfo.arguments()[1] as? Arg2, + let arg3 = aspectInfo.arguments()[2] as? Arg3, + let arg4 = aspectInfo.arguments()[3] as? Arg4, + let arg5 = aspectInfo.arguments()[4] as? Arg5, + let arg6 = aspectInfo.arguments()[5] as? Arg6, + let arg7 = aspectInfo.arguments()[6] as? Arg7 else { + return + } + usingBlock(aspectInfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + } + + let wrappedObject: AnyObject = unsafeBitCast(wrappedBlock, to: AnyObject.self) + do { + try aspect_hook(selector, with: options, usingBlock: wrappedObject) + } catch { + throw error + } + } +}