MethodNotificationCenter 0.1.1

MethodNotificationCenter 0.1.1

Maintained by Joseph Newton.



  • By
  • Joseph Newton

MethodNotificationCenter

Objective-C Runtime Injection

Codacy Badge License MIT CocoaPods Compatible Carthage Compatible Platform Code Coverage

Swift Package Xcode Project Cocoapods Carthage

MethodNotificationCenter is a lightweight framework for performing Objective-C runtime method injection for iOS, macOS, and tvOS.

Purpose

The purpose of this library is for being able to explore and understand the intricacies of the Objective-C runtime and the methods/APIs provided by Apple's libraries.

This library allows one to be notified, in a fashion very similar to Foundation's own NSNotificationCenter, before and after a given method is called on a particular object.

It should be noted that this library is for educational purposes only. The way in which this library operates not only makes it volatile and unsuitable to production releases, but use of it would likely not pass Apple's App Store review (untested).

Installation

MethodNotificationCenter is available through CocoaPods, Carthage and the Swift Package Manager.

To install via CocoaPods, simply add the following line to your Podfile:

pod 'MethodNotificationCenter'

To install via Carthage, simply add the following line to your Cartfile:

github "SomeRandomiOSDev/MethodNotificationCenter"

To install via the Swift Package Manager add the following line to your Package.swift file's dependencies:

.package(url: "https://github.com/SomeRandomiOSDev/MethodNotificationCenter.git", from: "1.0.0")

Usage

First import MethodNotificationCenter at the top of your source file:

Objective-C:

@import MethodNotificationCenter;

Swift:

import MethodNotificationCenter

After importing, simply use +[MethodNotificationCenter addObserverForSelector:object:callback:] to register a block handler for snooping in on Objective-C method calls:

Objective-C:

...
id observable = [MethodNotificationCenter addObserverForSelector:@selector(objectAtIndex:) object:array callback:^(MethodNotification *notification) {
    NSLog(@"NSArray's `objectAtIndex:` method was called");
}];

Swift:

...
let observable = MethodNotificationCenter.addObserver(for: #selector(NSArray.objectAtIndex(_:)), object:nsarray) { notification in
    print("NSArray's `objectAtIndex:` method was called")
}

Now your callback block will be called before and after each time the given selector is called on the object that you specified. When you are done snooping, simply pass the returned value from the registration method to +[MethodNotificationCenter removeObserver:]

Objective-C:

...
[MethodNotificationCenter removeObserver:observable];

Swift:

...
MethodNotificationCenter.removeObserver(observable)

Limitations

There are some notable limitations to the capabilities of this library:

  • Method notifications aren't sent recursively. That is, you'll receive a notification for the "top-level" call of the given method, but if the method (or any of its internal method calls) calls the same method a notification will not be sent for that.
  • Due to optimizations made by the Swift compiler, Swift calls to methods written in Swift (but annotated with the @objc attribute) are usually hard-coded by the compiler and don't use the Objective-C runtime, which prevent notifications from being sent. Classes written in Objective-C and called from Swift (or vice-versa) shouldn't have this issue. See Tests/MethodNotificationCenterTests/MethodNotificationCenterSwiftTests/MethodNotificationCenterTests.swift for examples.

Contributing

If you have need for a specific feature or you encounter a bug, please open an issue. If you extend the functionality of MethodNotificationCenter yourself or you feel like fixing a bug yourself, please submit a pull request.

Author

Joe Newton, [email protected]

License

MethodNotificationCenter is available under the MIT license. See the LICENSE file for more info.