# How to Set Different Video Quality for WiFi and Cellular in YTLite

> Learn how to set different video quality for WiFi and cellular in YTLite. Optimize your YTLite playback experience by configuring independent quality settings in the Playback section.

- Repository: [Dan/YTLite](https://github.com/dayanch96/YTLite)
- Tags: how-to-guide
- Published: 2026-04-22

---

**You can configure separate video quality settings for WiFi and cellular networks in YTLite through the Playback section of Settings, where the app stores independent quality indices in `wiFiQualityIndex` and `cellQualityIndex` user defaults.**

Every YouTube viewer knows the frustration of auto-playback selecting 4K on a limited data plan or dropping to 480p on a fast home connection. The YTLite tweak for iOS solves this by maintaining **two independent quality configurations**—one for **WiFi** and one for **cellular** networks. This article explains how these settings work under the hood, where they're stored, and how to access them programmatically.

---

## Where YTLite Stores WiFi and Cellular Quality Settings

YTLite persists your quality preferences using standard iOS **UserDefaults**, but with a custom subclass called `YTLUserDefaults`. The relevant keys are:

| Network Type | UserDefaults Key | Purpose |
|-------------|------------------|---------|
| WiFi | `wiFiQualityIndex` | Index (0-11) mapping to quality levels like "Best", "2160p60", "1080p", etc. |
| Cellular | `cellQualityIndex` | Same index scheme, applied when `Reachability` detects a cellular connection |

These values are **not** stored as strings like "1080p"—they're integer indices into a predefined array. This design makes comparison and application faster at playback time.

---

## How the Settings UI Works

The quality selection interface lives in **`Settings.x`** (lines 395-447). When you open **YTLite Settings → Playback**, you'll see two distinct rows:

- **Playback Quality on Wi-Fi**
- **Playback Quality on Cellular**

Each row uses a `detailTextBlock` to display the current quality as human-readable text, and a `selectBlock` to handle your selection.

### WiFi Quality Picker (Settings.x, lines 395-426)

```objc
YTSettingsSectionItem *wifiQuality = [YTSettingsSectionItemClass 
    itemWithTitle:LOC(@"PlaybackQualityOnWiFi")
    ...
    detailTextBlock:^NSString *{
        NSArray *qualityLabels = @[
            LOC(@"Default"), 
            LOC(@"Best"), 
            @"2160p60", 
            @"2160p", 
            @"1440p60", 
            @"1440p", 
            @"1080p60", 
            @"1080p", 
            @"720p60", 
            @"720p", 
            @"480p", 
            @"360p"
        ];
        return qualityLabels[ytlInt(@"wiFiQualityIndex")];
    }
    selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
        ...
        ytlSetInt((int)arg1, @"wiFiQualityIndex");
        return YES;
    }];

```

### Cellular Quality Picker (Settings.x, lines 423-447)

```objc
YTSettingsSectionItem *cellQuality = [YTSettingsSectionItemClass 
    itemWithTitle:LOC(@"PlaybackQualityOnCellular")
    ...
    detailTextBlock:^NSString *{
        NSArray *qualityLabels = @[
            LOC(@"Default"), 
            LOC(@"Best"), 
            @"2160p60", 
            // ... same array as WiFi
            @"360p"
        ];
        return qualityLabels[ytlInt(@"cellQualityIndex")];
    }
    selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
        ...
        ytlSetInt((int)arg1, @"cellQualityIndex");
        return YES;
    }];

```

Both pickers share the same **12-element quality array**, where index 0 is "Default" (let YouTube decide), index 1 is "Best" (highest available), and indices 2-11 map to specific resolutions with optional 60fps variants.

---

## The Helper Macros That Power Storage

YTLite doesn't call `NSUserDefaults` directly. Instead, it uses concise macros defined in **[`YTLite.h`](https://github.com/dayanch96/YTLite/blob/main/YTLite.h)** (lines 11-15):

```objc
#define ytlInt(key) [[YTLUserDefaults standardUserDefaults] integerForKey:key]
#define ytlSetInt(value, key) [[YTLUserDefaults standardUserDefaults] setInteger:(value) forKey:(key)]

```

These macros wrap the custom `YTLUserDefaults` class, which likely handles additional logic like migration or validation. For any programmatic access to quality settings, you should use these macros rather than raw `NSUserDefaults` calls.

---

## How YTLite Applies the Correct Quality at Playback

Static settings are useless without runtime detection. YTLite uses the **`Reachability`** utility (in `Reachability.m`, line 345) to determine the active network type:

```objc
BOOL isWiFi = [[Reachability reachabilityForInternetConnection] isReachableViaWiFi];

```

Based on this check, YTLite selects the appropriate defaults key:

```objc
NSString *qualityKey = isWiFi ? @"wiFiQualityIndex" : @"cellQualityIndex";
NSInteger qualityIdx = ytlInt(qualityKey);

```

The selected index is then passed to YouTube's internal `MLQuickMenuVideoQualitySettingFormatConstraint` mechanism to constrain the available video formats. This happens transparently during video load, so you never see the quality switch—it simply starts at your preferred resolution.

---

## Programmatic Examples for Developers

If you're building a custom tweak or debugging YTLite behavior, here are practical code snippets.

### Read Current WiFi Quality Setting

```objc
#import "YTLite.h"

NSInteger wifiIdx = ytlInt(@"wiFiQualityIndex");
NSArray *qualities = @[
    @"Default", @"Best", @"2160p60", @"2160p", @"1440p60",
    @"1440p", @"1080p60", @"1080p", @"720p60", @"720p",
    @"480p", @"360p"
];
NSString *currentWiFiQuality = qualities[wifiIdx];
NSLog(@"WiFi quality set to: %@", currentWiFiQuality);
// Output example: "WiFi quality set to: 1080p60"

```

### Force Cellular Quality Programmatically

```objc
// Set cellular quality to 720p60 (index 8)
NSInteger desiredCellularIdx = 8;
ytlSetInt(desiredCellularIdx, @"cellQualityIndex");

// Verify the change
NSInteger verifiedIdx = ytlInt(@"cellQualityIndex");
NSLog(@"Cellular quality now set to index: %ld", (long)verifiedIdx);

```

### Apply Settings on Network Change

```objc
#import "Reachability.h"
#import "YTLite.h"

- (void)applyQualityForCurrentNetwork {
    Reachability *reachability = [Reachability reachabilityForInternetConnection];
    NetworkStatus status = [reachability currentReachabilityStatus];
    
    NSString *key;
    NSString *networkType;
    
    if (status == ReachableViaWiFi) {
        key = @"wiFiQualityIndex";
        networkType = @"WiFi";
    } else if (status == ReachableViaWWAN) {
        key = @"cellQualityIndex";
        networkType = @"Cellular";
    } else {
        NSLog(@"No network connection");
        return;
    }
    
    NSInteger qualityIdx = ytlInt(key);
    NSLog(@"Applying %@ quality index: %ld", networkType, (long)qualityIdx);
    
    // Pass qualityIdx to MLQuickMenuVideoQualitySettingFormatConstraint here
}

```

---

## Key Source Files Reference

| File | Purpose | Location |
|------|---------|----------|
| `Settings.x` | UI implementation for WiFi and cellular quality pickers | Lines 395-426 (WiFi), 423-447 (cellular) |
| [`YTLite.h`](https://github.com/dayanch96/YTLite/blob/main/YTLite.h) | Macros `ytlInt` and `ytlSetInt` for defaults access | Lines 11-15 |
| [`Utils/YTLUserDefaults.h`](https://github.com/dayanch96/YTLite/blob/main/Utils/YTLUserDefaults.h) | Header for custom user defaults subclass | Root/Utils/ |
| `Utils/Reachability.m` | Network type detection at runtime | Line 345 (`isReachableViaWiFi`) |

---

## Summary

- **YTLite provides independent quality settings** for WiFi and cellular through two UserDefaults keys: `wiFiQualityIndex` and `cellQualityIndex`.
- **The settings UI** is located in `Settings.x` lines 395-447, using standard YouTube settings components with custom detail blocks and selection handlers.
- **Quality values are stored as integer indices** (0-11) into a fixed array, where 0 = Default, 1 = Best, and 2-11 = specific resolutions with optional 60fps.
- **Network detection** uses the `Reachability` class to apply the correct setting at video load time, transparently constraining available formats.
- **Developers can access these settings** through the `ytlInt` and `ytlSetInt` macros defined in [`YTLite.h`](https://github.com/dayanch96/YTLite/blob/main/YTLite.h).

---

## Frequently Asked Questions

### How do I access the WiFi and cellular quality settings in YTLite?

Open the YTLite Settings menu, navigate to the **Playback** section, and you'll see two distinct options: **Playback Quality on Wi-Fi** and **Playback Quality on Cellular**. Tap either to select your preferred resolution from the list.

### What happens if I set both WiFi and cellular quality to "Default"?

When set to **Default** (index 0), YTLite does not constrain the video format selection. YouTube's native adaptive streaming takes over, automatically selecting quality based on available bandwidth and screen size rather than your fixed preference.

### Can I programmatically change these settings from another tweak?

Yes. Include [`YTLite.h`](https://github.com/dayanch96/YTLite/blob/main/YTLite.h) in your project and use the `ytlSetInt(value, @"wiFiQualityIndex")` or `ytlSetInt(value, @"cellQualityIndex")` macros. The quality index maps to a 12-element array where 1 = Best, 2 = 2160p60, and so on down to 11 = 360p.

### Why does YTLite use integer indices instead of storing quality strings directly?

Integer indices provide **faster comparison operations** at runtime and **guarantee backward compatibility** if quality labels change. The `MLQuickMenuVideoQualitySettingFormatConstraint` system YouTube uses internally also operates on indexed format constraints, making direct integer mapping more efficient than string parsing during every video load.