All Projects → 623637646 → Swifthook

623637646 / Swifthook

Licence: mit
A library to hook methods in Swift and Objective-C.

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Swifthook

React Selector Hooks
Collection of hook-based memoized selector factories for declarations outside of render.
Stars: ✭ 84 (-9.68%)
Mutual labels:  hooks, hook
Anymethodlog
Log any method call of object in Objective-C
Stars: ✭ 361 (+288.17%)
Mutual labels:  hook, runtime
Radioactive State
☢ Make Your React App Truly Reactive!
Stars: ✭ 273 (+193.55%)
Mutual labels:  hooks, hook
hookr
PHP action and filter hook system
Stars: ✭ 39 (-58.06%)
Mutual labels:  hooks, hook
Stinger
Stinger is a high-efficiency library with great compatibility, for aop in Objective-C, using libffi instead of Objective-C message forwarding. It is 20+ times faster than the Aspects, from message-sending to Aspect-oriented code ends.
Stars: ✭ 845 (+808.6%)
Mutual labels:  hook, aop
MouseInjectDetection
Simple method of checking whether or not mouse movement or buttons (<windows 10) are injected
Stars: ✭ 29 (-68.82%)
Mutual labels:  hooks, hook
Swr
React Hooks for data fetching
Stars: ✭ 20,348 (+21779.57%)
Mutual labels:  hook, hooks
AppRun
AppDir runtime components
Stars: ✭ 19 (-79.57%)
Mutual labels:  hooks, runtime
Webhook
webhook is a lightweight incoming webhook server to run shell commands
Stars: ✭ 7,201 (+7643.01%)
Mutual labels:  hooks, hook
Blockhook
Hook Objective-C blocks. A powerful AOP tool.
Stars: ✭ 742 (+697.85%)
Mutual labels:  hooks, aop
Beike AspectD
Flutter AOP framework.(Flutter面向切面库, 最新适配Flutter v2.5.3, null-safety)
Stars: ✭ 39 (-58.06%)
Mutual labels:  hook, aop
Sandhook
Android ART Hook/Native Inline Hook/Single Instruction Hook - support 4.4 - 11.0 32/64 bit - Xposed API Compat
Stars: ✭ 1,172 (+1160.22%)
Mutual labels:  hook, aop
use-bus
React hook to subscribe and dispatch events accros React components
Stars: ✭ 51 (-45.16%)
Mutual labels:  hooks, hook
Ddetours
Delphi Detours Library
Stars: ✭ 256 (+175.27%)
Mutual labels:  hooks, runtime
rusty-hook
git hook manager, geared toward Rust projects
Stars: ✭ 93 (+0%)
Mutual labels:  hooks, hook
Epic
Dynamic java method AOP hook for Android(continution of Dexposed on ART), Supporting 5.0~11
Stars: ✭ 3,434 (+3592.47%)
Mutual labels:  hook, aop
CJMethodLog
Objective-C 函数日志监听系统,可监听任意类,任意类的任意方法的调用日志。
Stars: ✭ 26 (-72.04%)
Mutual labels:  hooks, runtime
useAudioPlayer
Custom React hook & context for controlling browser audio
Stars: ✭ 176 (+89.25%)
Mutual labels:  hooks, hook
Use Onclickoutside
React hook for listening for clicks outside of an element.
Stars: ✭ 361 (+288.17%)
Mutual labels:  hooks, hook
Fontmod
Simple hook tool to change Win32 program font.
Stars: ✭ 1,064 (+1044.09%)
Mutual labels:  hooks, hook

中文

What is SwiftHook?

A safe, easy, powerful and efficient hook library for iOS. It supports Swift and Objective-C. It has good compatibility with KVO.

It’s based on iOS runtime and libffi.

How to integrate SwiftHook?

SwiftHook can be integrated by cocoapods.

pod 'EasySwiftHook'

Feel free to send Pull Request to support Carthage or Swift Packages.

How to use SwiftHook

  1. Call the hook closure before executing specified instance’s method.
class MyObject { // This class doesn’t have to inherit from NSObject. of course inheriting from NSObject works fine.
    @objc dynamic func sayHello() { // The key words of methods `@objc` and `dynamic` are necessary.
        print("Hello!")
    }
}

do {
    let object = MyObject()
    // WARNING: the object will retain the closure. So make sure the closure doesn't retain the object to avoid memory leak by cycle retain. If you want to access the obeject, please refer to 2nd guide "XXX and get the parameters." below.
    let token = try hookBefore(object: object, selector: #selector(MyObject.sayHello)) {
        print("You will say hello, right?")
    }
    object.sayHello()
    token.cancelHook() // cancel the hook
} catch {
    XCTFail()
}
  1. Call the hook closure after executing specified instance's method and get the parameters.
class MyObject {
    @objc dynamic func sayHi(name: String) {
        print("Hi! \(name)")
    }
}

do {
    let object = MyObject()
    
    // 1. The first parameter mush be AnyObject or NSObject or YOUR CLASS (If it's YOUR CLASS. It has to inherits from NSObject, otherwise will build error with "XXX is not representable in Objective-C, so it cannot be used with '@convention(block)'").
    // 2. The second parameter mush be Selector.
    // 3. The rest parameters are the same as the method's.
    // 4. The return type mush be Void if you hook with `before` and `after` mode.
    // 5. The key word `@convention(block)` is necessary
    let hookClosure = { object, selector, name in
        print("Nice to see you \(name)")
        print("The object is: \(object)")
        print("The selector is: \(selector)")
    } as @convention(block) (AnyObject, Selector, String) -> Void
    let token = try hookAfter(object: object, selector: #selector(MyObject.sayHi), closure: hookClosure)
    
    object.sayHi(name: "Yanni")
    token.cancelHook()
} catch {
    XCTFail()
}
  1. Totally override the mehtod for specified instance.
class MyObject {
    @objc dynamic func sum(left: Int, right: Int) -> Int {
        return left + right
    }
}

do {
    let object = MyObject()
    
    // 1. The first parameter mush be an closure. This closure means original method. The closure's parameters and return type are the same with the original method's. 
    // 2. The rest parameters are the same with the original method's.
    // 3. The return type mush be the same with original method's.
    let hookClosure = {original, object, selector, left, right in
        let result = original(object, selector, left, right)
        // You may call original with the different parameters: let result = original(object, selector, 12, 27).
        // You also may change the object and selector if you want. You don't even have to call the original method if needed.
        print("\(left) + \(right) equals \(result)")
        return left * right // Changing the result
    } as @convention(block) ((AnyObject, Selector, Int, Int) -> Int, AnyObject, Selector, Int, Int) -> Int
    let token = try hookInstead(object: object, selector: #selector(MyObject.sum(left:right:)), closure: hookClosure)
    let left = 3
    let right = 4
    let result = object.sum(left: left, right: right)
    print("\(left) * \(right) equals \(result)")
    token.cancelHook()
} catch {
    XCTFail()
}
  1. Call the hook closure before executing the method for all instances of the class.
class MyObject {
    @objc dynamic func sayHello() {
        print("Hello!")
    }
}

do {
    let token = try hookBefore(targetClass: MyObject.self, selector: #selector(MyObject.sayHello)) {
        print("You will say hello, right?")
    }
    MyObject().sayHello()
    token.cancelHook()
} catch {
    XCTFail()
}
  1. Call the hook closure before executing the class method.
class MyObject {
    @objc dynamic class func sayHello() {
        print("Hello!")
    }
}

do {
    let token = try hookClassMethodBefore(targetClass: MyObject.self, selector: #selector(MyObject.sayHello)) {
        print("You will say hello, right?")
    }
    MyObject.sayHello()
    token.cancelHook()
} catch {
    XCTFail()
}
  1. Using in Objective-C

  2. Hooking the dealloc method

Performance

Comparing with Aspects (respect to Aspects).

  • Hook with Before and After mode for all instances, SwiftHook is 13 - 17 times faster than Aspects.
  • Hook with Instead mode for all instances, SwiftHook is 3 - 5 times faster than Aspects.
  • Hook with Before and After mode for specified instances, SwiftHook is 4 - 5 times faster than Aspects.
  • Hook with Instead mode for specified instances, SwiftHook is 2 - 4 times faster than Aspects.

Compatibility with KVO

SwiftHook is full compatible with KVO from 3.0.0 version. For more test cases: Here

We already have great Aspects. Why do I created SwiftHook?

  1. Aspects has some bugs. Click here for test code.
  2. Aspects doesn’t support Swift with instead mode in some cases. Click here for test code.
  3. Aspects’s API is not friendly for Swift.
  4. Aspects doesn’t support Swift object which is not based on NSObject.
  5. Aspects is based on message forward. This performance is not good.
  6. Aspects are no longer maintained. Author said: “STRICTLY DO NOT RECOMMEND TO USE Aspects IN PRODUCTION CODE
  7. Aspects is not compatible with KVO.

BTW, Respect to Aspects!

How it works?

  1. What is libffi.?
    1. Call C function at runtime.
    2. Create closure (IMP) at runtime.
  2. SwiftHook’s logic.

Requirements

  • iOS 10.0+ (Unverified for macOS, tvOS, watchOS)
  • Xcode 11+
  • Swift 5.0+

Stargazers over time

Stargazers over time

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].