Skip to content

Commit

Permalink
Updated to v1.0.5
Browse files Browse the repository at this point in the history
Added long press gesture for opening settings in the Settings.app
Added Spotlight indexing for searching and launching preference panes via Spotlight search
Fixed issue preventing Userspace Reboot and Reboot actions not to work for some users
Fixed issue causing Userspace Reboot action to show on unsupported devices
Fixed issue preventing universal URL's from working `tweaks:root=<IDENTIFIER>`
  • Loading branch information
CreatureSurvive committed Jun 14, 2021
1 parent 1529164 commit da87e77
Show file tree
Hide file tree
Showing 13 changed files with 188 additions and 23 deletions.
4 changes: 4 additions & 0 deletions Frameworks/Preferences.framework/Headers/PSSpecifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ __END_DECLS
@interface PSSpecifier : NSObject {
@public
SEL action;
Class detailControllerClass;
}

+ (instancetype)preferenceSpecifierNamed:(NSString *)identifier target:(id)target set:(SEL)set get:(SEL)get detail:(Class)detail cell:(PSCellType)cellType edit:(Class)edit;
Expand All @@ -143,4 +144,7 @@ __END_DECLS
@property (nonatomic) SEL controllerLoadAction;
- (Class)detailControllerClass;

-(SEL)controllerLoadAction;
-(void)performControllerLoadAction;

@end
4 changes: 2 additions & 2 deletions Frameworks/Preferences.framework/Headers/PSViewController.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@class PSSpecifier;
@class PSSpecifier, PSRootController;

@interface PSViewController : UIViewController

Expand All @@ -15,7 +15,7 @@

@property (nonatomic, retain) PSSpecifier *specifier;
@property (nonatomic, retain) PSViewController *parentController;
@property (nonatomic, retain) PSViewController *rootController;
@property (nonatomic, retain) PSRootController *rootController;

- (void)suspend;

Expand Down
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ export TARGET = iphone:clang:13.0:10.0
export ARCHS = armv7 arm64

DEBUG = 1
DEBUG_EXT =
FINALPACKAGE = 1
GO_EASY_ON_ME = 0
LEAN_AND_MEAN = 1
THEOS_PACKAGE_DIR = Releases
INSTALL_TARGET_PROCESSES = TweakSettings
PACKAGE_VERSION = $(THEOS_PACKAGE_BASE_VERSION)
PACKAGE_VERSION = $(THEOS_PACKAGE_BASE_VERSION)$(DEBUG_EXT)

include $(THEOS)/makefiles/common.mk

LAUNCH_URL =
XCODEPROJ_NAME = TweakSettings
TweakSettings_XCODEFLAGS = PACKAGE_VERSION='@\"$(THEOS_PACKAGE_BASE_VERSION)\"'
TweakSettings_CODESIGN_FLAGS = -SResources/entitlements.plist
Expand All @@ -23,6 +25,9 @@ include $(THEOS_MAKE_PATH)/aggregate.mk

after-stage::
$(ECHO_NOTHING)rm -f $(THEOS_STAGING_DIR)/Applications/TweakSettings.app/Localizable.strings$(ECHO_END)
$(ECHO_NOTHING)/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${THEOS_PACKAGE_BASE_VERSION}" "${THEOS_STAGING_DIR}/Applications/${XCODEPROJ_NAME}.app/Info.plist"$(ECHO_END)
$(ECHO_NOTHING)/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${PACKAGE_VERSION}" "${THEOS_STAGING_DIR}/Applications/${XCODEPROJ_NAME}.app/Info.plist"$(ECHO_END)
@echo "Set bundle version to: ${PACKAGE_VERSION}"

after-install::
install.exec "killall -9 TweakSettings; uicache -p /Applications/TweakSettings.app; uiopen tweaks:"
install.exec "killall -9 ${XCODEPROJ_NAME}; uicache -p /Applications/${XCODEPROJ_NAME}.app; uiopen tweaks:$(LAUNCH_URL)"
Binary file not shown.
4 changes: 4 additions & 0 deletions Resources/entitlements.plist
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,9 @@
<string>kTCCServiceFaceID</string>
<string>kTCCServiceMediaLibrary</string>
</array>

<!-- Allow oppening application urls -->
<key>com.apple.springboard.opensensitiveurl</key>
<true/>
</dict>
</plist>
1 change: 1 addition & 0 deletions TweakSettings-App/TSAppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
@property(strong, nonatomic) UIWindow *window;

- (void)handleActionForType:(NSString *)actionType withConfirmationSender:(id)sender;
- (void)openApplicationURL:(NSURL *)url;

@end
46 changes: 43 additions & 3 deletions TweakSettings-App/TSAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
//

#import <Preferences/PSRootController.h>
#import <CoreSpotlight/CoreSpotlight.h>
#import <dlfcn.h>
#import "TSAppDelegate.h"
#import "TSRootListController.h"
#import "Localizable.h"
Expand All @@ -19,6 +21,7 @@ @interface TSAppDelegate ()

@property(nonatomic, strong) PSRootController *rootController;
@property(nonatomic, strong) TSRootListController *rootListController;
@property(nonatomic, strong) NSString *launchIdentifier;

@end

Expand All @@ -38,6 +41,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(

_rootListController = [TSRootListController new];
_rootController = [[PSRootController alloc] initWithRootViewController:_rootListController];
_rootListController.rootController = _rootController;
_rootListController.launchIdentifier = _launchIdentifier;

self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
self.window.rootViewController = _rootController;
Expand Down Expand Up @@ -78,10 +83,16 @@ - (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {

if ([url.scheme isEqualToString:@"tweaks"]) {

NSString *urlString = url.absoluteString;

if ([urlString containsString:@"root="]) {
self.launchIdentifier = [urlString substringFromIndex:[urlString rangeOfString:@"root="].location + 5];
}

if ([url.scheme isEqualToString:@"tweaks:"]) {
[_rootController handleURL:url];
return YES;
}

Expand All @@ -94,6 +105,15 @@ - (void)application:(UIApplication *)application performActionForShortcutItem:(U
completionHandler(YES);
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler {

if ([userActivity.activityType isEqualToString:CSSearchableItemActionType]) {
self.launchIdentifier = [userActivity.userInfo[CSSearchableItemActivityIdentifier] stringByReplacingOccurrencesOfString:@"tweaks:root=" withString:@""];
}

return YES;
}

- (void)handleActionForType:(NSString *)actionType withConfirmationSender:(id)sender {

UIAlertController *controller = ActionAlertForType(actionType);
Expand All @@ -117,4 +137,24 @@ - (void)handleActionForType:(NSString *)actionType withConfirmationSender:(id)se
[self.rootController presentViewController:controller animated:YES completion:nil];
}

- (void)setLaunchIdentifier:(NSString *)launchIdentifier {

_launchIdentifier = [launchIdentifier stringByReplacingOccurrencesOfString:@"tweaks:root=" withString:@""];
_launchIdentifier = launchIdentifier;
_rootListController.launchIdentifier = launchIdentifier;

[_rootController popToRootViewControllerAnimated:NO];
[_rootListController pushToLaunchIdentifier];
}

- (void)openApplicationURL:(NSURL *)url {

void (*SBSOpenSensitiveURLAndUnlock)(NSURL *, BOOL);
if ((SBSOpenSensitiveURLAndUnlock = (void (*)(NSURL *, BOOL)) dlsym(RTLD_DEFAULT, "SBSOpenSensitiveURLAndUnlock"))) {
(*SBSOpenSensitiveURLAndUnlock)(url, YES);
} else if (@available(iOS 10,*)) {
[self openURL:url options:@{} completionHandler:nil];
}
}

@end
3 changes: 3 additions & 0 deletions TweakSettings-App/TSRootListController.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@

@interface TSRootListController : TSSearchableListController

@property (nonatomic, strong) NSString *launchIdentifier;

- (void)pushToLaunchIdentifier;
@end
98 changes: 95 additions & 3 deletions TweakSettings-App/TSRootListController.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@
//
//

#import <CoreSpotlight/CoreSpotlight.h>
#import <CoreServices/CoreServices.h>
#import <Preferences/PSSpecifier.h>
#import <dlfcn.h>
#import "TSRootListController.h"
#import "TSAppDelegate.h"
#import "Localizable.h"
#import "libprefs.h"
#import "TSAppDelegate.h"

@interface UIBarButtonItem (iOS14)
- (id)initWithTitle:(NSString *)table menu:(UIMenu *)menu API_AVAILABLE(ios(13.0));
@end

@interface TSRootListController ()

Expand All @@ -36,6 +42,12 @@ - (void)viewDidLoad {
self.table.refreshControl = _refreshControl;
}

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

[self pushToLaunchIdentifier];
}

- (NSMutableArray *)specifiers {
if (!_specifiers) {
NSMutableArray *specifiers = [self loadTweakSpecifiers].mutableCopy;
Expand All @@ -58,6 +70,28 @@ - (NSMutableArray *)specifiers {
return _specifiers;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if (!cell.gestureRecognizers.count) {
[cell addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleCellLongPress:)]];
}
return cell;
}

- (void)handleCellLongPress:(UILongPressGestureRecognizer *)sender {

if (sender.state == UIGestureRecognizerStateBegan) {

CGPoint point = [sender locationInView:self.table];
NSIndexPath *indexPath = [self.table indexPathForRowAtPoint:point];
PSSpecifier *specifier = [self specifierAtIndexPath:indexPath];
NSString *urlString = [NSString stringWithFormat:@"prefs:root=%@", specifier.identifier];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]];

[(TSAppDelegate *)UIApplication.sharedApplication openApplicationURL:url];
}
}

- (NSArray<PSSpecifier *> *)loadTweakSpecifiers {
NSMutableArray *preferenceSpecifiers = [NSMutableArray new];

Expand Down Expand Up @@ -92,7 +126,7 @@ - (NSMutableArray *)specifiers {
}

NSBundle *prefBundle = [NSBundle bundleWithPath:(isBundle ? bundlePath : sourceBundlePath)];
NSArray *bundleControllers = [listController valueForKey:@"_bundleControllers"];
NSMutableArray *bundleControllers = [listController valueForKey:@"_bundleControllers"];

void *handle = dlopen("/System/Library/PrivateFrameworks/Preferences.framework/Preferences", RTLD_LAZY);
NSArray *(*_SpecifiersFromPlist)(NSDictionary *,PSSpecifier *,id ,NSString *,NSBundle *,NSString **,NSString **,PSListController *,NSMutableArray **) = dlsym(handle, "SpecifiersFromPlist");
Expand Down Expand Up @@ -130,13 +164,14 @@ - (NSMutableArray *)specifiers {
};

NSArray *preferenceBundlePaths = [NSFileManager.defaultManager subpathsOfDirectoryAtPath:@"/Library/PreferenceLoader/Preferences" error:nil];
NSMutableArray *searchableItems = [NSMutableArray new];

for (NSString *item in preferenceBundlePaths)
{
if (![item.pathExtension isEqualToString:@"plist"]) continue;

NSString *plistPath = [NSString stringWithFormat:@"/Library/PreferenceLoader/Preferences/%@", item];
NSDictionary *plist = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSDictionary *plist = DICTIONARY_WITH_PLIST(plistPath);

if (!plist[@"entry"]) continue;
if (!PREFERENCE_FILTER_PASSES_ENVIRONMENT_CHECKS(plist[@"filter"] ?: plist[@"pl_filter"])) continue;
Expand All @@ -153,6 +188,23 @@ - (NSMutableArray *)specifiers {

if (itemSpecifiers && itemSpecifiers.count)
{
for (PSSpecifier *specifier in itemSpecifiers)
{
if (![specifier propertyForKey:PSIconImageKey]) {
[specifier setProperty:[UIImage imageNamed:@"tweak"] forKey:PSIconImageKey];
}

CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *) kUTTypeImage];
attributeSet.title = specifier.name;
attributeSet.contentDescription = [NSString stringWithFormat:@"Tweak Settings \u2192 %@", specifier.name];
attributeSet.thumbnailData = UIImagePNGRepresentation([specifier propertyForKey:PSIconImageKey]);
attributeSet.keywords = @[@"tweaks", @"packages", @"jailbreak", specifier.name];

NSString *uniqueIdentifier = [NSString stringWithFormat:@"%@", specifier.identifier];
CSSearchableItem *searchItem = [[CSSearchableItem alloc] initWithUniqueIdentifier:uniqueIdentifier domainIdentifier:@"com.creaturecoding.tweaksettings" attributeSet:attributeSet];
[searchableItems addObject:searchItem];
}

[preferenceSpecifiers addObjectsFromArray:itemSpecifiers];
}
}
Expand All @@ -163,6 +215,10 @@ - (NSMutableArray *)specifiers {
];
}

[CSSearchableIndex.defaultSearchableIndex deleteAllSearchableItemsWithCompletionHandler:^(NSError *error) {
[CSSearchableIndex.defaultSearchableIndex indexSearchableItems:searchableItems completionHandler:nil];
}];

return preferenceSpecifiers;
}

Expand All @@ -176,4 +232,40 @@ - (void)handleActionButtonTapped:(UIBarButtonItem *)sender {
[self.navigationController presentViewController:ActionListAlert(sender) animated:YES completion:nil];
}

- (void)pushToLaunchIdentifier {

if (_launchIdentifier) {
PSSpecifier *specifier = [self specifierForID:_launchIdentifier];

if (specifier) {

[specifier performControllerLoadAction];

Class detailClass = [specifier respondsToSelector:@selector(detailControllerClass)]
? [specifier detailControllerClass]
: [specifier valueForKey:@"detailControllerClass"]
? : NSClassFromString(@"PLCustomListController");

if ([detailClass isSubclassOfClass:PSViewController.class]) {

id controller = [detailClass alloc];
controller = ([controller respondsToSelector:@selector(initForContentSize:)])
? [controller initForContentSize:UIScreen.mainScreen.bounds.size]
: [controller init];

if (controller && [controller isKindOfClass:PSViewController.class]) {

[controller setRootController:self.rootController];
[controller setParentController:self];
[controller setSpecifier:specifier];
}

[self.navigationController pushViewController:controller animated:NO];
}
}
}

_launchIdentifier = nil;
}

@end
11 changes: 4 additions & 7 deletions TweakSettings-App/TSUtilityActionManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,14 @@ int HandleActionForType(NSString *actionType) {
[menuActions addObject:[UIAction actionWithTitle:NSLocalizedString(REBOOT_TITLE_KEY, nil) image:nil identifier:nil handler:^(__kindof UIAction *action) {
[((TSAppDelegate *)UIApplication.sharedApplication) handleActionForType:TSActionTypeReboot withConfirmationSender:sender];
}]];
[menuActions addObject:[UIAction actionWithTitle:NSLocalizedString(USREBOOT_TITLE_KEY, nil) image:nil identifier:nil handler:^(__kindof UIAction *action) {
[((TSAppDelegate *)UIApplication.sharedApplication) handleActionForType:TSActionTypeUserspaceReboot withConfirmationSender:sender];
}]];
if (userspace_supported) {
[UIAction actionWithTitle:NSLocalizedString(USREBOOT_TITLE_KEY, nil) image:nil identifier:nil handler:^(__kindof UIAction *action) {
[menuActions addObject:[UIAction actionWithTitle:NSLocalizedString(USREBOOT_TITLE_KEY, nil) image:nil identifier:nil handler:^(__kindof UIAction *action) {
[((TSAppDelegate *)UIApplication.sharedApplication) handleActionForType:TSActionTypeUserspaceReboot withConfirmationSender:sender];
}];
}]];
}
[UIAction actionWithTitle:NSLocalizedString(TWEAKINJECT_TITLE_KEY, nil) image:nil identifier:nil handler:^(__kindof UIAction *action) {
[menuActions addObject:[UIAction actionWithTitle:NSLocalizedString(TWEAKINJECT_TITLE_KEY, nil) image:nil identifier:nil handler:^(__kindof UIAction *action) {
[((TSAppDelegate *)UIApplication.sharedApplication) handleActionForType:TSActionTypeTweakInject withConfirmationSender:sender];
}];
}]];

return [UIMenu menuWithTitle:@"" children:menuActions];
}
Loading

0 comments on commit da87e77

Please sign in to comment.