Skip to content

Instantly share code, notes, and snippets.

@donato-fiore
Last active April 4, 2025 20:27
Show Gist options
  • Save donato-fiore/cd0ed25114d121646387157cbbda622b to your computer and use it in GitHub Desktop.
Save donato-fiore/cd0ed25114d121646387157cbbda622b to your computer and use it in GitHub Desktop.
Visually load and unload specific `PSSpecifier`'s based on a different `PSSpecifier`'s value
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>cell</key>
<key>PSSwitchCell</key>
<key>default</key>
<false/>
<key>defaults</key>
<string>com.example.tweak.prefs</string>
<key>key</key>
<string>kSomeBoolValue</string>
<key>label</key>
<string>PSSwitchCell</string>
<key>PostNotification</key>
<string>com.example.tweak.prefs/ReloadPrefs</string>
</dict>
<dict>
<key>cell</key>
<string>PSStaticTextCell</string>
<key>label</key>
<string>PSStaticTextCell</string>
<key>dependsOn</key>
<!--
Special cases:
'*' - Multiple dependencies, all must be true
'!' - Inverse dependency, if true, this specifier is hidden
-->
<string>kSomeBoolValue</string>
</dict>
</array>
<key>title</key>
<string>title</string>
</dict>
</plist>
#import <Preferences/PSListController.h>
@interface TweakRootListController : PSListController
- (NSMutableArray *)visibleSpecifiersFromPlist:(NSString *)plist;
@end
@implementation TweakRootListController
- (NSArray *)specifiers {
if (!_specifiers) {
_specifiers = [self visibleSpecifiersFromPlist:@"Root"];
}
return _specifiers;
}
- (void)setPreferenceValue:(id)value specifier:(PSSpecifier *)specifier {
[super setPreferenceValue:value specifier:specifier];
[self reloadSpecifiers];
}
- (NSMutableArray *)visibleSpecifiersFromPlist:(NSString *)plist {
NSDictionary *preferences = /* load your preferences here */;
NSMutableArray *specifiers = [[self loadSpecifiersFromPlistName:plist target:self] mutableCopy];
for (PSSpecifier *specifier in [specifiers reverseObjectEnumerator]) {
NSString *dependency = [specifier propertyForKey:@"dependsOn"];
if (dependency) {
if ([dependency containsString:@"*"]) { // Multiple dependencies
NSArray *dependencies = [dependency componentsSeparatedByString:@"*"];
BOOL allDependenciesMet = YES;
for (NSString *dep in dependencies) {
if (![[preferences objectForKey:dep] boolValue]) {
allDependenciesMet = NO;
break;
}
}
if (!allDependenciesMet) {
[specifiers removeObject:specifier];
}
} else { // Single dependency
if ([dependency containsString:@"!"]) {
dependency = [dependency stringByReplacingOccurrencesOfString:@"!" withString:@""];
if ([[preferences objectForKey:dependency] boolValue]) {
[specifiers removeObject:specifier];
}
} else {
if (![[preferences objectForKey:dependency] boolValue]) {
[specifiers removeObject:specifier];
}
}
}
}
}
return specifiers;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment