Skip to content

Instantly share code, notes, and snippets.

@MTACS
Last active November 30, 2023 22:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save MTACS/68506061b452fe1bf05fc20f9e5a233a to your computer and use it in GitHub Desktop.
Save MTACS/68506061b452fe1bf05fc20f9e5a233a to your computer and use it in GitHub Desktop.
Hosted Preference bundle

Hosted Preference Bundles

Create a "hosted" view of a preference bundle outside of Preferences.app, and in a dedicated application.

For application

  • Create new tweak using "iphone/application_modern" template
  • In the app's delegate file add the following to the -(void)applicationDidFinishLaunching:(UIApplication *)application; method:
/* TweakApplicationDelegate.h */

@interface TweakApplicationDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, retain) UIWindow *window;
@property (nonatomic, retain) UINavigationController *rootViewController;
@end

/* TweakApplicationDelegate.m */

@implementation TweakApplicationDelegate
- (void)applicationDidFinishLaunching:(UIApplication *)application {
    _window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

    NSBundle *bundle = [NSBundle bundleWithPath:@"/Library/PreferenceBundles/TweakPreferences.bundle"];
    [bundle load];
    if ([bundle isLoaded]) {
        _rootViewController = [[UINavigationController alloc] initWithRootViewController:[bundle.principalClass new]];
    } else {
        UIViewController *preferencesController = [[UIViewController alloc] init];
        _rootViewController = [[UINavigationController alloc] initWithRootViewController:preferencesController];
    }
    _window.rootViewController = _rootViewController;
    [_window makeKeyAndVisible];
}
@end

For use as view controller

/* Tweak.h */

@interface TweakPreferencesController: UIViewController
@end

/* Tweak.xm */

%hook SomeViewController
- (void)presentPreferencesController:(id)sender {
    NSBundle *bundle = [NSBundle bundleWithPath:@"/Library/PreferenceBundles/TweakPreferences.bundle"];
    [bundle load];
    if ([bundle isLoaded]) {
        TweakPreferencesController *rootController = [objc_getClass("TweakPreferencesController") new]; // Tweak preference bundle principal class
        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootController];
        [self presentViewController:navigationController animated:YES completion:nil];
    }
}
%end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment