How to Hook into the YouTube iOS App with YTLite: A Complete Developer Guide
YTLite leverages Logos syntax and the Substrate framework to inject Objective-C hooks into the YouTube iOS binary at runtime, replacing methods in classes like YTPlayerViewController via %hook blocks while reading user toggles from YTLUserDefaults.
YTLite is a Cydia/Substrate tweak that enables deep customization of the official YouTube iOS app through runtime method hooking. By utilizing the Logos preprocessor language and the Theos build system, developers can intercept and modify YouTube's native behavior without touching the original App Store binary. This guide explains the architecture of how to hook into the YouTube iOS app with YTLite and demonstrates how to implement your own modifications using the source code from the dayanch96/YTLite repository.
Understanding the YTLite Hooking Architecture
YTLite acts as a dynamic library (.dylib) that Substrate loads into the YouTube process at launch. The core hooking logic resides in YTLite.x, which contains Logos directives that target specific YouTube Objective-C classes.
The hooking pipeline follows five distinct stages:
- Injection – Substrate loads the compiled
YTLite.dylibwhen the YouTube app starts. - Class Resolution – At load time, Logos resolves each
%hook ClassNamedirective to the real Objective-C class object inside the YouTube binary. - Method Swizzling – For every method inside a
%hookblock, Logos creates a new implementation (IMP) that can call the original via%orig. - Preference Lookup – Inside each hook, macros like
ytlBool(@"key")read values fromYTLUserDefaultsto determine if custom logic should execute. - Execution – When YouTube calls a hooked selector, the injected implementation runs, applying modifications such as hiding ads or changing UI elements.
All YouTube class definitions are imported via YouTubeHeaders.h, which re-exports the de-compiled header files so the compiler recognizes method signatures for classes like YTPlayerViewController, YTWatchViewController, and YTReelPlayerViewController.
Core Components You Will Modify
To successfully hook into the YouTube iOS app with YTLite, you will interact with these specific source files:
| File | Purpose | Key Functionality |
|---|---|---|
YTLite.x |
Main Logos source | Contains every %hook … %end block that patches YouTube methods at runtime. |
YouTubeHeaders.h |
Header bridge | Imports de-compiled YouTube headers required for class and method visibility. |
YTLite.h |
Macro definitions | Defines ytlBool, ytlInt, LOC, and other helpers used inside hooks. |
Utils/YTLUserDefaults.h |
Settings backend | Thin wrapper around NSUserDefaults storing toggle states accessed by the macros. |
YTLite.plist |
Default values | Holds the default boolean and integer values for every toggle in the tweak. |
Makefile |
Build configuration | Theos makefile that compiles the dynamic library and packages the .deb. |
How to Add a Custom Hook to YouTube
Below is a step-by-step workflow for adding a new feature that changes the video player’s background color when a specific toggle is enabled.
Step 1: Define the Toggle in YTLite.plist
Add your preference key to YTLite.plist with a default value of NO:
<key>darkPlayerBG</key>
<false/>
Step 2: Write the Hook in YTLite.x
Open YTLite.x and add a new %hook block targeting the player view class:
%hook YTPlayerView
- (void)layoutSubviews {
%orig; // Preserve original layout logic
if (ytlBool(@"darkPlayerBG")) {
self.backgroundColor = [UIColor colorWithWhite:0.15 alpha:1.0];
}
}
%end
Code Explanation:
%hook YTPlayerViewtells Logos to intercept methods belonging to YouTube's player view class.%origpreserves the originallayoutSubviewsimplementation, ensuring standard UI setup occurs first.ytlBool(@"darkPlayerBG")queriesYTLUserDefaultsfor the toggle state defined in the plist.- The background color only changes when the user has explicitly enabled the feature.
Step 3: Compile and Install
Use Theos to build the package from the repository root:
make package
For jailbroken devices, install the resulting .deb:
dpkg -i YTLite_*.deb
For non-jailbroken devices, build a .ipa and sideload it using AltStore.
Real-World Example: Disabling Autoplay
YTLite already ships with a hook that disables YouTube’s autoplay functionality. This demonstrates reading a toggle and conditionally altering method arguments:
%hook YTPlaybackConfig
- (void)setStartPlayback:(BOOL)arg1 {
// If disableAutoplay is enabled, force NO; otherwise, pass original value
ytlBool(@"disableAutoplay") ? %orig(NO) : %orig;
}
%end
This hook intercepts YTPlaybackConfig's setStartPlayback: method. When the disableAutoplay toggle is active in YTLUserDefaults, it forces the arg1 parameter to NO via %orig(NO), preventing automatic video start. Otherwise, it calls %orig with the original argument intact.
The Hook Lifecycle in Detail
When you hook into the YouTube iOS app with YTLite, the following runtime mechanics occur:
- Target Resolution – Logos resolves
%hook YTPlayerViewto the actual class object loaded by YouTube's binary using the Objective-C runtime. - IMP Replacement – Substrate replaces the method's implementation pointer in the class method table with your new custom function generated from the
%hookblock. - Original Preservation – Logos generates a function pointer accessible via
%origthat points to the original YouTube implementation, allowing you to call or conditionally bypass the native behavior. - Preference Integration – The
ytlBoolmacro defined inYTLite.htranslates to a call to[YTLUserDefaults standardUserDefaults]with the specific key, enabling dynamic feature gating without recompilation.
Summary
- Hook Syntax – Use
%hook ClassNameand%endblocks inYTLite.xto target YouTube classes, with%origto invoke original implementations. - Preferences – Store toggle keys in
YTLite.plistand read them inside hooks usingytlBool()orytlInt()macros fromYTLite.h. - Headers – Import
YouTubeHeaders.hto access YouTube class definitions required for compilation. - Build Process – Compile with Theos (
make package) to generate a Substrate-compatible dynamic library that injects at runtime.
Frequently Asked Questions
What is Logos and why does YTLite use it?
Logos is a preprocessor language created by Theos that simplifies Objective-C method hooking. It abstracts the complex method_exchangeImplementations calls into readable %hook syntax. YTLite uses Logos because it allows developers to write concise patches—like %orig to call original methods—without manually handling pointer manipulation, making the codebase in YTLite.x maintainable and readable.
How does YTLite read user preferences inside hooks?
YTLite uses macros defined in YTLite.h that wrap NSUserDefaults calls. When you write ytlBool(@"key") inside a hook, it expands to a call to [[YTLUserDefaults standardUserDefaults] boolForKey:@"key"]. The values are persisted in YTLUserDefaults (backed by NSUserDefaults) and initialized with defaults from YTLite.plist at launch.
Can I use YTLite on a non-jailbroken device?
Yes, but it requires sideloading. While YTLite is designed for Substrate injection on jailbroken devices (placing the .dylib in /Library/MobileSubstrate/DynamicLibraries/), you can build a modified .ipa using Theos and load it onto a non-jailbroken iPhone via AltStore or similar sideloading tools. The hooking mechanism remains identical, but injection happens through the sideloading framework rather than Substrate.
Where do I find the class names to hook in YouTube?
YouTube class names are defined in YouTubeHeaders.h. This file imports the de-compiled headers from the original YouTube binary, exposing classes like YTPlayerViewController, YTReelPlayerViewController, and YTPlaybackConfig. Inspecting these headers reveals the exact method signatures required to write valid %hook blocks that compile against YouTube's private APIs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →