Skip to content

Instantly share code, notes, and snippets.

@AbodiDawoud
Created December 2, 2025 02:18
Show Gist options
  • Select an option

  • Save AbodiDawoud/e8071c042841727549f3dc12c987bd5a to your computer and use it in GitHub Desktop.

Select an option

Save AbodiDawoud/e8071c042841727549f3dc12c987bd5a to your computer and use it in GitHub Desktop.

Debug Overrides

This is a copy of debug overrides available through Xcode UI that boils down to calling certain private APIs. It only overrides the values within your app while it's running, restarting the app will reset back to the system values

This simply wraps overrides found in /Applications/Xcode.app/Contents/PlugIns/IDEiOSDebugger.ideplugin/Contents/Resources/IDEiOSDebugger.xcplugindata into C functions Probably not a good idea to ship those to the AppStore Most of APIs work by setting one @YES or @NO to set value explicitly, or by setting nil to reset to the system value

#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, DBGInterfaceStyleOverride) {
DBGInterfaceStyleOverrideNone = 0,
DBGInterfaceStyleOverrideLight,
DBGInterfaceStyleOverrideDark,
};
#ifdef __cplusplus
extern "C" {
#endif
/**
* No Override = nil
* Enabled = @YES
* Disabled = @NO
*/
void DBGSetSmartInvert(NSNumber *value);
/**
* No Override = nil
* Enabled = @YES
* Disabled = @NO
*/
void DBGSetGrayscale(NSNumber *value);
/**
* No Override = nil
* Enabled = @YES
* Disabled = @NO
*/
void DBGSetButtonShapes(NSNumber *value);
/**
* No Override = nil
* Enabled = @YES
* Disabled = @NO
*/
void DBGSetOnOffLabels(NSNumber *value);
/**
* No Override = nil
* Reduced = @YES
* Default = @NO
*/
void DBGSetReduceTransparency(NSNumber *value);
/**
* No Override = 0
* Light = 1
* Dark = 2
*/
void DBGSetInterfaceStyle(DBGInterfaceStyleOverride value);
/**
* No Override = nil
* Enabled = @YES
* Disabled = @NO
*/
void DBGSetDifferentiateWithoutColor(NSNumber *value);
/**
* No Override = nil
* Reduced = @YES
* Default = @NO
*/
void DBGSetReduceMotion(NSNumber *value);
/**
* No Override = nil
* Extra Small = UIContentSizeCategoryExtraSmall
* Small = UIContentSizeCategorySmall
* Medium = UIContentSizeCategoryMedium
* Large = UIContentSizeCategoryLarge
* XL = UIContentSizeCategoryExtraLarge
* XXL = UIContentSizeCategoryExtraExtraLarge
* XXXL = UIContentSizeCategoryExtraExtraExtraLarge
* Accessibility Medium = UIContentSizeCategoryAccessibilityMedium
* Accessibility Large = UIContentSizeCategoryAccessibilityLarge
* Accessibility XL = UIContentSizeCategoryAccessibilityExtraLarge
* Accessibility XXL = UIContentSizeCategoryAccessibilityExtraExtraLarge
* Accessibility XXXL = UIContentSizeCategoryAccessibilityExtraExtraExtraLarge
*/
void DBGSetDynamicType(UIContentSizeCategory value);
/**
* No Override = nil
* Increased = @YES
* Default = @NO
*/
void DBGSetIncreaseContrast(NSNumber *value);
/**
* No Override = nil
* Enabled = @YES
* Disabled = @NO
*/
void DBGSetBoldText(NSNumber *value);
#ifdef __cplusplus
}
#endif
#import "DebugOverrides.h"
#import <objc/runtime.h>
@interface DebugOverridesSelectorsHost: NSObject
+ (instancetype)shared;
- (instancetype)initWithContentSizeCategory:(UIContentSizeCategory)value;
- (void)setSmartInvert:(NSNumber *)value;
- (void)setGrayscale:(NSNumber *)value;
- (void)setButtonShapes:(NSNumber *)value;
- (void)setOnOffLabels:(NSNumber *)value;
- (void)setReduceTransparency:(NSNumber *)value;
- (void)_setDebugUserInterfaceStyleOverride:(DBGInterfaceStyleOverride)value;
- (void)setDifferentiateWithoutColor:(NSNumber *)value;
- (void)setReduceMotion:(NSNumber *)value;
- (void)overrideSystemWithPreference:(id)value;
- (void)setIncreaseContrast:(NSNumber *)value;
- (void)setBoldText:(NSNumber *)value;
@end
void DBGSetSmartInvert(NSNumber *value) {
[[objc_getClass("AccessibilitySupportOverrides") shared] setSmartInvert:value];
}
void DBGSetGrayscale(NSNumber *value) {
[[objc_getClass("AccessibilitySupportOverrides") shared] setGrayscale:value];
}
void DBGSetButtonShapes(NSNumber *value) {
[[objc_getClass("AccessibilitySupportOverrides") shared] setButtonShapes:value];
}
void DBGSetOnOffLabels(NSNumber *value) {
[[objc_getClass("AccessibilitySupportOverrides") shared] setOnOffLabels:value];
}
void DBGSetReduceTransparency(NSNumber *value) {
[[objc_getClass("AccessibilitySupportOverrides") shared] setReduceTransparency:value];
}
void DBGSetInterfaceStyle(DBGInterfaceStyleOverride value) {
[objc_getClass("UIApplication") _setDebugUserInterfaceStyleOverride:value];
}
void DBGSetDifferentiateWithoutColor(NSNumber *value) {
[[objc_getClass("AccessibilitySupportOverrides") shared] setDifferentiateWithoutColor:value];
}
void DBGSetReduceMotion(NSNumber *value) {
[[objc_getClass("AccessibilitySupportOverrides") shared] setReduceMotion:value];
}
void DBGSetDynamicType(UIContentSizeCategory value) {
[objc_getClass("UIContentSizeCategoryPreference") overrideSystemWithPreference:[[objc_getClass("UIContentSizeCategoryPreference") alloc] initWithContentSizeCategory:value]];
}
void DBGSetIncreaseContrast(NSNumber *value) {
[[objc_getClass("AccessibilitySupportOverrides") shared] setIncreaseContrast:value];
}
void DBGSetBoldText(NSNumber *value) {
[[objc_getClass("AccessibilitySupportOverrides") shared] setBoldText:value];
}
//
// DebugOverridesView.swift
// FreeSpace
import SwiftUI
struct DebugOverridesView: View {
@State private var smartInvert: Bool? = nil
@State private var grayscale: Bool? = nil
@State private var buttonShapes: Bool? = nil
@State private var reduceTransparency: Bool? = nil
@State private var interfaceStyle: DBGInterfaceStyleOverride = .none
@State private var reduceMotion: Bool? = nil
@State private var boldText: Bool? = nil
var body: some View {
NavigationView {
Form {
// Smart Invert
Section(header: Text("Accessibility Settings")) {
Toggle("Smart Invert", isOn: Binding(
get: { smartInvert ?? false },
set: { newValue in
smartInvert = newValue
DebugOverridesWrapper.setSmartInvert(newValue)
}
))
Toggle("Grayscale", isOn: Binding(
get: { grayscale ?? false },
set: { newValue in
grayscale = newValue
DebugOverridesWrapper.setGrayscale(newValue)
}
))
Toggle("Button Shapes", isOn: Binding(
get: { buttonShapes ?? false },
set: { newValue in
buttonShapes = newValue
DebugOverridesWrapper.setButtonShapes(newValue)
}
))
Toggle("Reduce Transparency", isOn: Binding(
get: { reduceTransparency ?? false },
set: { newValue in
reduceTransparency = newValue
DebugOverridesWrapper.setReduceTransparency(newValue)
}
))
Toggle("Reduce Motion", isOn: Binding(
get: { reduceMotion ?? false },
set: { newValue in
reduceMotion = newValue
DebugOverridesWrapper.setReduceMotion(newValue)
}
))
Toggle("Bold Text", isOn: Binding(
get: { boldText ?? false },
set: { newValue in
boldText = newValue
DebugOverridesWrapper.setBoldText(newValue)
}
))
}
// Interface Style
Section(header: Text("Interface Style")) {
Picker("Interface Style", selection: $interfaceStyle) {
Text("None").tag(DBGInterfaceStyleOverride.none)
Text("Light").tag(DBGInterfaceStyleOverride.light)
Text("Dark").tag(DBGInterfaceStyleOverride.dark)
}
.pickerStyle(SegmentedPickerStyle())
.onChange(of: interfaceStyle) { _, newValue in
DebugOverridesWrapper.setInterfaceStyle(newValue.rawValue)
}
}
Section {
Button("AXPreferences") {
AccessibilityWrapper.axPreferences()
}
Button("ToggleSmartInvertColors") {
AccessibilityWrapper.toggleSmartInvertColors()
}
}
}
.navigationTitle("Debug Overrides")
}
}
}
class DebugOverridesWrapper: NSObject {
static func setSmartInvert(_ enabled: Bool?) {
let value = enabled.map { NSNumber(value: $0) }
DBGSetSmartInvert(value)
}
static func setGrayscale(_ enabled: Bool?) {
let value = enabled.map { NSNumber(value: $0) }
DBGSetGrayscale(value)
}
static func setButtonShapes(_ enabled: Bool?) {
let value = enabled.map { NSNumber(value: $0) }
DBGSetButtonShapes(value)
}
static func setOnOffLabels(_ enabled: Bool?) {
let value = enabled.map { NSNumber(value: $0) }
DBGSetOnOffLabels(value)
}
static func setReduceTransparency(_ enabled: Bool?) {
let value = enabled.map { NSNumber(value: $0) }
DBGSetReduceTransparency(value)
}
static func setInterfaceStyle(_ style: Int) {
DBGSetInterfaceStyle(DBGInterfaceStyleOverride(rawValue: style) ?? .none)
}
static func setDifferentiateWithoutColor(_ enabled: Bool?) {
let value = enabled.map { NSNumber(value: $0) }
DBGSetDifferentiateWithoutColor(value)
}
static func setReduceMotion(_ enabled: Bool?) {
let value = enabled.map { NSNumber(value: $0) }
DBGSetReduceMotion(value)
}
static func setDynamicType(_ size: UIContentSizeCategory) {
DBGSetDynamicType(size)
}
static func setIncreaseContrast(_ enabled: Bool?) {
let value = enabled.map { NSNumber(value: $0) }
DBGSetIncreaseContrast(value)
}
static func setBoldText(_ enabled: Bool?) {
let value = enabled.map { NSNumber(value: $0) }
DBGSetBoldText(value)
}
}
class AccessibilityWrapper {
static func setVoiceOver(_ enabled: Bool) {
let path = "/System/Library/PrivateFrameworks/AccessibilityUtilities.framework/AccessibilityUtilities"
let handle = dlopen(path, RTLD_NOW)
defer { dlclose(handle) }
guard let voiceOverFunction = dlsym(handle, "_AXSVoiceOverTouchSetEnabled")
else { return print("Couldn't find voiceOver function") }
typealias VoiceOverFunctionType = @convention(c) (Bool) -> Void
let _AXSVoiceOverTouchSetEnabled = unsafeBitCast(voiceOverFunction, to: VoiceOverFunctionType.self)
_AXSVoiceOverTouchSetEnabled(enabled)
print("VoiceOver Toggled.")
}
static func axPreferences() {
let path = "/System/Library/PrivateFrameworks/AccessibilityUtilities.framework/AccessibilityUtilities"
let handle = dlopen(path, RTLD_NOW)
defer { dlclose(handle) }
let classObject = objc_getClass("AXPreferences") as! NSObject.Type
let shared = classObject.value(forKey: "shared") as! NSObject
let liveSpeech = shared.value(forKey: "liveSpeech")
print(liveSpeech as Any)
}
static func toggleSmartInvertColors() {
let path = "/System/Library/PrivateFrameworks/AccessibilityUtilities.framework/AccessibilityUtilities"
let handle = dlopen(path, RTLD_NOW)
defer { dlclose(handle) }
let classObject = objc_getClass("AXTripleClickHelpers") as! NSObject.Type
classObject.perform(Selector(("toggleGuidedAccess")))
}
}
//
// FreeSpace-Bridging-Header.h.h
#import "DebugOverrides.h"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment