How YTLite Manages Preferences and Data Using YTLUserDefaults

YTLite stores all user settings in a dedicated NSUserDefaults suite named com.dvntm.ytlite, accessed through a singleton YTLUserDefaults class that provides macaque-wrapped getters, setters, and reset functionality.

The YTLite tweak for YouTube iOS manages every user-configurable feature—from ad blocking to playback speed—through a centralized preference system built on YTLUserDefaults. This lightweight subclass of NSUserDefaults ensures consistent state across the entire tweak while providing a clean API for both direct access and macro-based convenience.

What Is YTLUserDefaults?

YTLUserDefaults is a specialized subclass defined in Utils/YTLUserDefaults.h and implemented in Utils/YTLUserDefaults.m. Unlike standard NSUserDefaults, it scopes all operations to a specific suite name (com.dvntm.ytlite) and enforces a singleton pattern to prevent multiple instances from desynchronizing preferences.

The class serves three core functions: creating a thread-safe singleton, registering baseline defaults on first launch, and providing a complete reset mechanism.

The Singleton Pattern and Suite Initialization

The +standardUserDefaults class method in Utils/YTLUserDefaults.m (lines 7-13) implements a classic GCD-based singleton:

+ (YTLUserDefaults *)standardUserDefaults {
    static YTLUserDefaults *defaults = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        defaults = [[self alloc] initWithSuiteName:kDefaultsSuiteName];
        [defaults registerDefaults];
    });
    return defaults;
}

Key implementation details:

  • dispatch_once guarantees exactly one initialization regardless of thread contention
  • initWithSuiteName: creates an isolated preferences container that persists across app launches
  • registerDefaults immediately populates the suite with baseline values

The suite name constant kDefaultsSuiteName is defined as @"com.dvntm.ytlite", ensuring YTLite's preferences don't conflict with YouTube's own settings or other tweaks.

Registering Baseline Configuration

The -registerDefaults method (lines 23-34 in Utils/YTLUserDefaults.m) establishes every toggle's initial state:

- (void)registerDefaults {
    [self registerDefaults:@{
        @"noAds": @YES,
        @"backgroundPlayback": @YES,
        // ... additional default keys
    }];
}

This baseline dictionary is critical for YTLite's behavior: it ensures that every feature has a defined value even before the user opens Settings for the first time. The NSUserDefaults -registerDefaults: method is non-destructive—it only sets values for keys that don't already exist, preserving any user changes across updates.

The Macro Façade for Daily Use

While direct YTLUserDefaults access works, YTLite's codebase primarily uses convenience macros defined in YTLite.h (lines 11-15). These macros provide terse, type-safe access to preferences throughout the tweak:

Macro Purpose Example Usage
ytlBool(key) Read BOOL value if (ytlBool(@"noAds")) { ... }
ytlInt(key) Read NSInteger value NSInteger speed = ytlInt(@"speedIndex");
ytlSetBool(value, key) Write BOOL ytlSetBool(NO, @"noAds");
ytlSetInt(value, key) Write NSInteger ytlSetInt(2, @"speedIndex");

These macros expand to direct YTLUserDefaults method calls, maintaining the singleton pattern while eliminating boilerplate. For example, ytlBool(@"noAds") expands to [[YTLUserDefaults standardUserDefaults] boolForKey:@"noAds"].

Practical Usage Examples

Direct Singleton Access

For code requiring explicit control or testing, the singleton methods are available:

// Reading a preference
BOOL adsDisabled = [[YTLUserDefaults standardUserDefaults] boolForKey:@"noAds"];

// Writing a preference
[[YTLUserDefaults standardUserDefaults] setBool:YES 
                                        forKey:@"backgroundPlayback"];

Using Convenience Macros

The typical pattern throughout YTLite.x and other implementation files:

// Feature-gating based on user preference
if (ytlBool(@"noAds")) {
    // ... remove advertisement views from hierarchy
}

// Adjusting playback behavior
ytlSetInt(2, @"speedIndex");  // Set to 2× speed
NSInteger currentSpeed = ytlInt(@"speedIndex");

Resetting All Preferences

The Settings UI provides a "Reset All Settings" option that calls:

[YTLUserDefaults resetUserDefaults];

This class method (defined in Utils/YTLUserDefaults.m lines 36-38) immediately clears the entire com.dvntm.ytlite suite, restoring all defaults on next launch.

The Reset Mechanism

Complete preference wiping is handled by two methods in Utils/YTLUserDefaults.m (lines 19-22 and 36-38):

- (void)reset {
    [self removePersistentDomainForName:kDefaultsSuiteName];
}

+ (void)resetUserDefaults {
    [[self standardUserDefaults] reset];
}

The instance method -reset uses NSUserDefaults' -removePersistentDomainForName: to atomically delete all keys in the suite. The class method provides the convenient entry point used by Settings.x at line 594 when users confirm the reset action.

Key Files in the Preference System

File Purpose Location
Utils/YTLUserDefaults.h Class declaration and public API Utils/YTLUserDefaults.h
Utils/YTLUserDefaults.m Singleton implementation, defaults registration, reset logic Utils/YTLUserDefaults.m
YTLite.h Macro definitions (ytlBool, ytlSetInt, etc.) YTLite.h
Settings.x UI implementation including reset functionality Settings.x
YTLite.x Primary usage of preference macros for feature gating YTLite.x

Summary

  • YTLUserDefaults is a specialized NSUserDefaults subclass that scopes all YTLite preferences to the com.dvntm.ytlite suite
  • The singleton pattern with dispatch_once ensures thread-safe, single-instance access across the entire tweak
  • Baseline defaults are registered automatically on first launch, giving every feature a defined initial state
  • Convenience macros (ytlBool, ytlSetInt, etc.) provide terse, type-safe access throughout the codebase
  • Complete reset is available through [YTLUserDefaults resetUserDefaults], which clears the entire suite

Frequently Asked Questions

What is the difference between YTLUserDefaults and standard NSUserDefaults?

YTLUserDefaults is a subclass that creates an isolated suite named com.dvntm.ytlite, keeping YTLite's preferences completely separate from YouTube's own settings or other tweaks. It also adds singleton enforcement, default registration, and reset functionality that standard NSUserDefaults doesn't provide.

How does YTLUserDefaults handle first-time installation?

On first access to [YTLUserDefaults standardUserDefaults], the dispatch_once block calls -registerDefaults, which populates the suite with baseline values for every toggle (e.g., noAds: @YES). This ensures the tweak works immediately after installation without requiring users to configure anything first.

Can I use YTLUserDefaults for my own iOS tweak?

The pattern is highly reusable. The key components are: a suite name constant, a singleton accessor with dispatch_once, default registration, and convenience macros. However, you should change kDefaultsSuiteName to your own reverse-DNS identifier to avoid conflicts with YTLite or other tweaks.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →