All Projects → sushinoya → Lumos

sushinoya / Lumos

Licence: apache-2.0
💡 A light Swift wrapper around Objective-C Runtime

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Lumos

Drf Api Tracking
Fork of aschn/drf-tracking so that we can maintain and release newer versions
Stars: ✭ 117 (-1.68%)
Mutual labels:  hacktoberfest
Syft.js
The official Syft worker for Web and Node, built in Javascript
Stars: ✭ 118 (-0.84%)
Mutual labels:  hacktoberfest
Pytrustnfe
Módulo NF-e Python
Stars: ✭ 118 (-0.84%)
Mutual labels:  hacktoberfest
React Spring Slider
A slider component for react
Stars: ✭ 118 (-0.84%)
Mutual labels:  hacktoberfest
Config Lint
Command line tool to validate configuration files
Stars: ✭ 118 (-0.84%)
Mutual labels:  hacktoberfest
Yii2 App Advanced
Yii 2.0 Advanced Application Template
Stars: ✭ 1,569 (+1218.49%)
Mutual labels:  hacktoberfest
Percona
Development repository for the percona cookbook
Stars: ✭ 117 (-1.68%)
Mutual labels:  hacktoberfest
Useful Dev Tools
⭐️ A list with useful tools that help many Developers. Hacktoberfest ⭐️
Stars: ✭ 119 (+0%)
Mutual labels:  hacktoberfest
Camunda External Task Client Js
Implement your BPMN Service Task in NodeJS.
Stars: ✭ 118 (-0.84%)
Mutual labels:  hacktoberfest
Mangaki
Site de recommandation de mangas et d'anime
Stars: ✭ 118 (-0.84%)
Mutual labels:  hacktoberfest
Menu
A JavaScript free menu library for Blazor and Razor Components applications.
Stars: ✭ 118 (-0.84%)
Mutual labels:  hacktoberfest
My Internet Speed
🛎️ Monitor the speed your ISP is delivering
Stars: ✭ 118 (-0.84%)
Mutual labels:  hacktoberfest
Vsc Material Theme
Material Theme, the most epic theme for Visual Studio Code
Stars: ✭ 1,617 (+1258.82%)
Mutual labels:  hacktoberfest
Gatsby Themes
Gatsby themes that we use to build websites at Rocketseat ⚡️🔥
Stars: ✭ 116 (-2.52%)
Mutual labels:  hacktoberfest
Hacktoberfest2021
Raise Genuine PRs, Your PRs will be accepted, Star This Repo, You aren't allowed to Update README.md
Stars: ✭ 119 (+0%)
Mutual labels:  hacktoberfest
Trading Signals
Technical indicators to run technical analysis with JavaScript / TypeScript. 📈
Stars: ✭ 118 (-0.84%)
Mutual labels:  hacktoberfest
Call For Papers
List with open Call for Papers
Stars: ✭ 118 (-0.84%)
Mutual labels:  hacktoberfest
Pg ha migrations
Enforces DDL/migration safety in Ruby on Rails project with an emphasis on explicitly choosing trade-offs and avoiding unnecessary magic.
Stars: ✭ 119 (+0%)
Mutual labels:  hacktoberfest
Unshort.link
Prevent short link services from tracking you by unshortening the urls for your
Stars: ✭ 119 (+0%)
Mutual labels:  hacktoberfest
Universal Collapsingtablayout
CollapsingToolbarLayout with TabLayout
Stars: ✭ 118 (-0.84%)
Mutual labels:  hacktoberfest
LMMethod Methods

A light wrapper around Objective-C Runtime.

What exactly is lumos?

lumos as mentioned is a light wrapper around objective-c runtime functions to allow an easier access to the runtime. It makes operations such as swizzling and hooking very simple in Swift.

For example, say you wish to run a block of code whenever a ViewController's viewDidLoad method is called

With lumos, you can do the following:

// In AppDelegate (or any conveinient place)..

let method = Lumos.for(ViewController.self).getInstanceMethod(selector: #selector(ViewController.viewDidLoad))
        
method?.prepend {
    // This block will be run every time a viewDidLoad is called
    print("View Controller loaded")
}

Similarily you can append a block to a method which will be called right before the method returns. You can even use replace to replace the method's implementation with the block you pass in as a parameter.

If you wanted more flexibility, you could swizzle the viewDidLoad method using the following lines:

@objc func myMethod() {
    // Do anything here
}

let myMethod = self.lumos.getInstanceMethod(selector: #selector(myMethod))

method?.swapImplementation(with: myMethod)

Do you feel the superpower yet? Maybe you wish to list all the classes registered at runtime:

Lumos.getAllClasses()

Fun Fact: There are almost 12,000 classes registered at runtime Try Lumos.getAllClasses().count

You could get the class hierarchy of any class just with:

myObject.lumos.getClassHierarcy()   // For UIView: [UIView, UIResponder, NSObject]

Fun Fact: Some classes such as URLSessionTask are actually dummy classes which are replaced with underlying classes such as __NSCFLocalSessionTask during runtime.

With lumos, you can iterate through variables, functions, protocols etc and meddle with them at runtime. Have fun exploring!

Usage

Just incantate .lumos on any instance of a NSObject subclass or use Lumos.for(object) for where object is of type AnyClass, AnyObject, Protocol, Ivar, objc_property_t or objc_property_attribute_t.

LMMethod Methods LMClass Methods

P.s The code itself is the documentation for now. There are many more methods that lumos offers which are not discussed in this document. Cheers :)

Why lumos?

The Objective-C Runtime provides many powerful methods to manipulate objects, classes and methods at runtime. Although disasterous when misused, these methods provide a great way to peek into the runtime and meddle with it.

However, the methods are not exactly easy to use sometimes. For example the following method is used to obtain a list of all classes registered at runtime:

func objc_getClassList(_ buffer: AutoreleasingUnsafeMutablePointer<AnyClass>?, _ bufferCount: Int32) -> Int32

Often, a lot of dirty work needs to be done before one gets the list out. Here is how I would do it:

static func getClassList() -> [AnyClass] {
    let expectedClassCount = objc_getClassList(nil, 0)
    let allClasses = UnsafeMutablePointer<AnyClass?>.allocate(capacity: Int(expectedClassCount))

    let autoreleasingAllClasses = AutoreleasingUnsafeMutablePointer<AnyClass>(allClasses)
    let actualClassCount: Int32 = objc_getClassList(autoreleasingAllClasses, expectedClassCount)

    var classes = [AnyClass]()
    for i in 0 ..< actualClassCount {
        if let currentClass: AnyClass = allClasses[Int(i)] {
            classes.append(currentClass)
        }
    }

    allClasses.deallocate()
    return classes
}

Now all you would need to do to obtain the list of classes would be to invoke this method. Maybe you wish to get a list of classes that conform to a certain protocol:

static func classesImplementingProtocol(_ requiredProtocol: Protocol) -> [AnyClass] {
    return Lumos.getClassList().filter { class_conformsToProtocol($0, requiredProtocol) }
}

Perhaps you wish to swizzle method implementations at runtime:

static func swizzle(originalClass: AnyClass, originalSelector: Selector, swizzledClass: AnyClass, swizzledSelector: Selector) {
    guard let originalMethod = class_getInstanceMethod(originalClass, originalSelector),
    let swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector) else {
        return
    }

    let didAddMethod = class_addMethod(originalClass, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

    if didAddMethod {
        class_replaceMethod(originalClass, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

You can now use:

Lumos.swizzle(originalClass: URLSessionTask,
              originalSelector: #selector(URLSessionTask.resume),
              swizzledClass: SwizzledSessionTask,
              swizzledSelector: #selector(SwizzledSessionTask.resume))

P.S you might want to use dispatch_once with the method above to above swizzling more than once across multiple threads.

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate lumos into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'Lumos'
end

Then, run the following command:

$ pod install

License

Lumos is released under the Apache-2.0. See LICENSE for details.

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].