Skip to content

Commit

Permalink
Update AppIconOptionsController.m
Browse files Browse the repository at this point in the history
  • Loading branch information
aricloverALT authored Aug 25, 2024
1 parent a21aeff commit f9df1ce
Showing 1 changed file with 92 additions and 76 deletions.
168 changes: 92 additions & 76 deletions Sources/AppIconOptionsController.m
Original file line number Diff line number Diff line change
@@ -1,133 +1,149 @@
// AppIconOptionsController.m
#import <UIKit/UIKit.h>
#import <CydiaSubstrate/CydiaSubstrate.h>
#import <YouTubeHeader/YTAssetLoader.h>
#import "AppIconOptionsController.h"
#import <Foundation/Foundation.h>
#import <SpringBoard/SpringBoard.h>
#import <objc/runtime.h>
#import <sys/utsname.h>

@interface AppIconOptionsController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#define kAppIconOptionsControllerKey @"AppIconOptionsController"

@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSArray *appIcons;
@property (nonatomic, assign) NSInteger selectedIconIndex;
@interface AppIconOptionsController : UIViewController

@property (strong, nonatomic) UITableView *tableView;
@property (strong, nonatomic) NSArray<NSString *> *appIcons;
@property (assign, nonatomic) NSInteger selectedIconIndex;

@end

@implementation AppIconOptionsController

- (void)viewDidLoad {
[super viewDidLoad];

self.title = @"Change App Icon";

self.view.backgroundColor = [UIColor whiteColor];
self.selectedIconIndex = -1;

self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.view addSubview:self.tableView];

self.appIcons = [self loadAppIcons];

self.appIcons = [self getAppIcons];
if (![UIApplication sharedApplication].supportsAlternateIcons) {
NSLog(@"Alternate icons are not supported on this device.");
return;
}
}

- (NSArray *)loadAppIcons {
// Assuming you have your custom icons in a bundle named "AppIcons" inside your tweak
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"AppIcons" ofType:@"bundle"]];
if (bundle) {
return [bundle pathsForResourcesOfType:@"png" inDirectory:nil];
} else {
NSLog(@"Error loading app icons bundle");
return nil;
- (NSArray<NSString *> *)getAppIcons {
NSMutableArray *icons = [NSMutableArray array];
NSBundle *bundle = [NSBundle mainBundle];
NSArray *iconFiles = [bundle pathsForResourcesOfType:@"png" inDirectory:@"AppIcons"];

for (NSString *iconFile in iconFiles) {
[icons addObject:iconFile];
}

return [icons copy];
}

#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.appIcons.count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60.0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AppIconCell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"AppIconCell"];
}

NSString *iconPath = self.appIcons[indexPath.row];
cell.textLabel.text = [iconPath.lastPathComponent stringByDeletingPathExtension];

UIImage *iconImage = [UIImage imageWithContentsOfFile:iconPath];
cell.imageView.image = iconImage;
cell.imageView.layer.cornerRadius = 10.0;
cell.imageView.clipsToBounds = YES;
cell.imageView.frame = CGRectMake(10, 10, 40, 40);
cell.textLabel.frame = CGRectMake(60, 10, self.view.frame.size.width - 70, 40);

if (indexPath.row == self.selectedIconIndex) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}

}
return cell;
}

#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];

self.selectedIconIndex = indexPath.row;
[self.tableView reloadData];
}

#pragma mark - Icon Change Methods
- (void)saveIcon {
if (![UIApplication sharedApplication].supportsAlternateIcons) {
NSLog(@"Alternate icons are not supported on this device.");
if (self.selectedIconIndex < 0 || self.selectedIconIndex >= self.appIcons.count) {
NSLog(@"No icon selected.");
return;
}

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *selectedIcon = self.selectedIconIndex >= 0 ? self.appIcons[self.selectedIconIndex] : nil;
if (selectedIcon) {
NSString *iconName = [selectedIcon.lastPathComponent stringByDeletingPathExtension];

LSApplicationWorkspace *workspace = [LSApplicationWorkspace defaultWorkspace];
[workspace setAlternateIconName:iconName forApplicationWithBundleIdentifier:[[NSBundle mainBundle] bundleIdentifier] completionHandler:^(NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"Error setting alternate icon: %@", error.localizedDescription);
} else {
NSLog(@"Alternate icon set successfully");
}
});
}];
NSString *selectedIconPath = self.appIcons[self.selectedIconIndex];
NSString *iconName = [selectedIconPath.lastPathComponent stringByDeletingPathExtension];
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
[infoDict setObject:iconName forKey:@"ALTAppIcon"];
[infoDict writeToFile:plistPath atomically:YES];
[[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
if (error) {
NSLog(@"Error setting alternate icon: %@", error.localizedDescription);
} else {
NSLog(@"Selected icon path is nil");
NSLog(@"Alternate icon set successfully.");
}
});
}];
}

- (void)resetIcon {
if (![UIApplication sharedApplication].supportsAlternateIcons) {
NSLog(@"Alternate icons are not supported on this device.");
return;
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
[infoDict removeObjectForKey:@"ALTAppIcon"];
[infoDict writeToFile:plistPath atomically:YES];
[[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^(NSError * _Nullable error) {
if (error) {
NSLog(@"Error resetting icon: %@", error.localizedDescription);
} else {
NSLog(@"Icon reset successfully.");
}
}];
}
+ (NSString *)getDeviceModel {
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}
+ (SBApplication *)getSpringBoard {
Class springBoardClass = NSClassFromString(@"SBApplication");
return (SBApplication *)[springBoardClass performSelector:NSSelectorFromString(@"sharedApplication")];
}
+ (SBIconController *)getIconController {
SBApplication *springBoard = [self getSpringBoard];
if (springBoard) {
return (SBIconController *)[springBoard performSelector:NSSelectorFromString(@"_iconController")];
}

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
LSApplicationWorkspace *workspace = [LSApplicationWorkspace defaultWorkspace];
[workspace setAlternateIconName:nil forApplicationWithBundleIdentifier:[[NSBundle mainBundle] bundleIdentifier] completionHandler:^(NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"Error resetting icon: %@", error.localizedDescription);
} else {
NSLog(@"Icon reset successfully");
}
});
}];
return nil;
}
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self addAppIconOptionsButtonToSpringBoard];
});
}

+ (void)addAppIconOptionsButtonToSpringBoard {
dispatch_async(dispatch_get_main_queue(), ^{
SBApplication *springBoard = [self getSpringBoard];
SBIconController *iconController = [self getIconController];
UIButton *appIconOptionsButton = [UIButton buttonWithType:UIButtonTypeCustom];
[appIconOptionsButton setTitle:@"App Icons" forState:UIControlStateNormal];
[appIconOptionsButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[appIconOptionsButton addTarget:self action:@selector(presentAppIconOptionsViewController) forControlEvents:UIControlEventTouchUpInside];
appIconOptionsButton.frame = CGRectMake(100, 100, 100, 50);
[springBoard.view addSubview:appIconOptionsButton];
});
}
+ (void)presentAppIconOptionsViewController {
SBApplication *springBoard = [self getSpringBoard];
AppIconOptionsController *appIconOptionsController = [[AppIconOptionsController alloc] init];
UIViewController *rootViewController = springBoard.rootViewController;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:appIconOptionsController];
[rootViewController presentViewController:navigationController animated:YES completion:nil];
}
@end

0 comments on commit f9df1ce

Please sign in to comment.