diff --git a/Store/TSAppTableViewController.h b/Store/TSAppTableViewController.h index 904bf0f..3f3910d 100644 --- a/Store/TSAppTableViewController.h +++ b/Store/TSAppTableViewController.h @@ -1,5 +1,9 @@ #import @interface TSAppTableViewController : UITableViewController +{ + UIImage* _placeholderIcon; + NSArray* _cachedAppPaths; +} @end \ No newline at end of file diff --git a/Store/TSAppTableViewController.m b/Store/TSAppTableViewController.m index d354ec6..fa0f252 100644 --- a/Store/TSAppTableViewController.m +++ b/Store/TSAppTableViewController.m @@ -8,182 +8,212 @@ @implementation TSAppTableViewController +- (void)loadCachedAppPaths +{ + _cachedAppPaths = [[TSApplicationsManager sharedInstance] installedAppPaths]; +} + +- (instancetype)init +{ + self = [super init]; + if(self) + { + [self loadCachedAppPaths]; + _placeholderIcon = [UIImage _applicationIconImageForBundleIdentifier:@"com.apple.WebSheet" format:10 scale:[UIScreen mainScreen].scale]; + } + return self; +} + - (void)reloadTable { - dispatch_async(dispatch_get_main_queue(), ^ - { - [self.tableView reloadData]; - }); + [self loadCachedAppPaths]; + dispatch_async(dispatch_get_main_queue(), ^ + { + [self.tableView reloadData]; + }); } - (void)loadView { - [super loadView]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(reloadTable) - name:@"ApplicationsChanged" - object:nil]; + [super loadView]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(reloadTable) + name:@"ApplicationsChanged" + object:nil]; } - (void)viewDidLoad { - [super viewDidLoad]; - - self.tableView.allowsMultipleSelectionDuringEditing = NO; + [super viewDidLoad]; + + self.tableView.allowsMultipleSelectionDuringEditing = NO; } - (void)showError:(NSError*)error { - UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Error %ld", error.code] message:error.localizedDescription preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil]; - [errorAlert addAction:closeAction]; - [self presentViewController:errorAlert animated:YES completion:nil]; + UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Error %ld", error.code] message:error.localizedDescription preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil]; + [errorAlert addAction:closeAction]; + [self presentViewController:errorAlert animated:YES completion:nil]; } - (void)openAppPressedForRowAtIndexPath:(NSIndexPath *)indexPath { - TSApplicationsManager* appsManager = [TSApplicationsManager sharedInstance]; + TSApplicationsManager* appsManager = [TSApplicationsManager sharedInstance]; - NSString* appPath = [appsManager installedAppPaths][indexPath.row]; - NSString* appId = [appsManager appIdForAppPath:appPath]; - BOOL didOpen = [appsManager openApplicationWithBundleID:appId]; + NSString* appPath = _cachedAppPaths[indexPath.row]; + NSString* appId = [appsManager appIdForAppPath:appPath]; + BOOL didOpen = [appsManager openApplicationWithBundleID:appId]; - // if we failed to open the app, show an alert - if (!didOpen) { - NSString *failMessage = [NSString stringWithFormat: @"Failed to open %@", appId]; - UIAlertController* didFailController = [UIAlertController alertControllerWithTitle:failMessage message: nil preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]; + // if we failed to open the app, show an alert + if (!didOpen) { + NSString *failMessage = [NSString stringWithFormat: @"Failed to open %@", appId]; + UIAlertController* didFailController = [UIAlertController alertControllerWithTitle:failMessage message: nil preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]; - [didFailController addAction: cancelAction]; - [self presentViewController:didFailController animated:YES completion:nil]; - } + [didFailController addAction: cancelAction]; + [self presentViewController:didFailController animated:YES completion:nil]; + } } - (void)uninstallPressedForRowAtIndexPath:(NSIndexPath*)indexPath { - TSApplicationsManager* appsManager = [TSApplicationsManager sharedInstance]; + TSApplicationsManager* appsManager = [TSApplicationsManager sharedInstance]; - NSString* appPath = [appsManager installedAppPaths][indexPath.row]; - NSString* appId = [appsManager appIdForAppPath:appPath]; - NSString* appName = [appsManager displayNameForAppPath:appPath]; + NSString* appPath = _cachedAppPaths[indexPath.row]; + NSString* appId = [appsManager appIdForAppPath:appPath]; + NSString* appName = [appsManager displayNameForAppPath:appPath]; - UIAlertController* confirmAlert = [UIAlertController alertControllerWithTitle:@"Confirm Uninstallation" message:[NSString stringWithFormat:@"Uninstalling the app '%@' will delete the app and all data associated to it.", appName] preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController* confirmAlert = [UIAlertController alertControllerWithTitle:@"Confirm Uninstallation" message:[NSString stringWithFormat:@"Uninstalling the app '%@' will delete the app and all data associated to it.", appName] preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction* uninstallAction = [UIAlertAction actionWithTitle:@"Uninstall" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action) - { - if(appId) - { - [appsManager uninstallApp:appId]; - } - else - { - [appsManager uninstallAppByPath:appPath]; - } - }]; - [confirmAlert addAction:uninstallAction]; + UIAlertAction* uninstallAction = [UIAlertAction actionWithTitle:@"Uninstall" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action) + { + if(appId) + { + [appsManager uninstallApp:appId]; + } + else + { + [appsManager uninstallAppByPath:appPath]; + } + }]; + [confirmAlert addAction:uninstallAction]; - UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]; - [confirmAlert addAction:cancelAction]; + UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]; + [confirmAlert addAction:cancelAction]; - [self presentViewController:confirmAlert animated:YES completion:nil]; + [self presentViewController:confirmAlert animated:YES completion:nil]; } - (void)deselectRow { - [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES]; + [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES]; } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; + return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return [[TSApplicationsManager sharedInstance] installedAppPaths].count; + return _cachedAppPaths.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ApplicationCell"]; - if (!cell) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"ApplicationCell"]; - } + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ApplicationCell"]; + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"ApplicationCell"]; + } - NSString* appPath = [[TSApplicationsManager sharedInstance] installedAppPaths][indexPath.row]; - NSString* appId = [[TSApplicationsManager sharedInstance] appIdForAppPath:appPath]; - NSString* appVersion = [[TSApplicationsManager sharedInstance] versionStringForAppPath:appPath]; + NSString* appPath = _cachedAppPaths[indexPath.row]; + NSString* appId = [[TSApplicationsManager sharedInstance] appIdForAppPath:appPath]; + NSString* appVersion = [[TSApplicationsManager sharedInstance] versionStringForAppPath:appPath]; - // Configure the cell... - cell.textLabel.text = [[TSApplicationsManager sharedInstance] displayNameForAppPath:appPath]; - cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ • %@", appVersion, appId]; - cell.imageView.image = [UIImage _applicationIconImageForBundleIdentifier:appId format:10 scale:[UIScreen mainScreen].scale]; - cell.imageView.layer.borderWidth = 0.2; - cell.imageView.layer.borderColor = [UIColor blackColor].CGColor; - cell.imageView.layer.cornerRadius = 13.8; + // Configure the cell... + cell.textLabel.text = [[TSApplicationsManager sharedInstance] displayNameForAppPath:appPath]; + cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ • %@", appVersion, appId]; + cell.imageView.image = _placeholderIcon; + cell.imageView.layer.borderWidth = 0.2; + cell.imageView.layer.borderColor = [UIColor blackColor].CGColor; + cell.imageView.layer.cornerRadius = 13.8; - cell.preservesSuperviewLayoutMargins = NO; - cell.separatorInset = UIEdgeInsetsZero; - cell.layoutMargins = UIEdgeInsetsZero; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ + { + //usleep(1000 * 5000); // (test delay for debugging) + UIImage* iconImage = [UIImage _applicationIconImageForBundleIdentifier:appId format:10 scale:[UIScreen mainScreen].scale]; + dispatch_async(dispatch_get_main_queue(), ^{ + if([tableView.indexPathsForVisibleRows containsObject:indexPath]) + { + cell.imageView.image = iconImage; + } + }); + }); - return cell; + cell.preservesSuperviewLayoutMargins = NO; + cell.separatorInset = UIEdgeInsetsZero; + cell.layoutMargins = UIEdgeInsetsZero; + + return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - return 80.0f; + return 80.0f; } - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { - if(editingStyle == UITableViewCellEditingStyleDelete) - { - [self uninstallPressedForRowAtIndexPath:indexPath]; - } + if(editingStyle == UITableViewCellEditingStyleDelete) + { + [self uninstallPressedForRowAtIndexPath:indexPath]; + } } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - TSApplicationsManager* appsManager = [TSApplicationsManager sharedInstance]; + TSApplicationsManager* appsManager = [TSApplicationsManager sharedInstance]; - NSString* appPath = [appsManager installedAppPaths][indexPath.row]; - NSString* appId = [appsManager appIdForAppPath:appPath]; - NSString* appName = [appsManager displayNameForAppPath:appPath]; + NSString* appPath = _cachedAppPaths[indexPath.row]; + NSString* appId = [appsManager appIdForAppPath:appPath]; + NSString* appName = [appsManager displayNameForAppPath:appPath]; - UIAlertController* appSelectAlert = [UIAlertController alertControllerWithTitle:appName message:appId preferredStyle:UIAlertControllerStyleActionSheet]; + UIAlertController* appSelectAlert = [UIAlertController alertControllerWithTitle:appName message:appId preferredStyle:UIAlertControllerStyleActionSheet]; - /*UIAlertAction* detachAction = [UIAlertAction actionWithTitle:@"Detach from TrollStore" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action) - { - int detachRet = [appsManager detachFromApp:appId]; - if(detachRet != 0) - { - [self showError:[appsManager errorForCode:detachRet]]; - } - [self deselectRow]; - }]; - [appSelectAlert addAction:detachAction];*/ + /*UIAlertAction* detachAction = [UIAlertAction actionWithTitle:@"Detach from TrollStore" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action) + { + int detachRet = [appsManager detachFromApp:appId]; + if(detachRet != 0) + { + [self showError:[appsManager errorForCode:detachRet]]; + } + [self deselectRow]; + }]; + [appSelectAlert addAction:detachAction];*/ - UIAlertAction* openAction = [UIAlertAction actionWithTitle: @"Open" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action) - { - [self openAppPressedForRowAtIndexPath:indexPath]; - }]; - [appSelectAlert addAction: openAction]; + UIAlertAction* openAction = [UIAlertAction actionWithTitle: @"Open" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action) + { + [self openAppPressedForRowAtIndexPath:indexPath]; + [self deselectRow]; + }]; + [appSelectAlert addAction: openAction]; - UIAlertAction* uninstallAction = [UIAlertAction actionWithTitle:@"Uninstall App" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action) - { - [self uninstallPressedForRowAtIndexPath:indexPath]; - [self deselectRow]; - }]; - [appSelectAlert addAction:uninstallAction]; + UIAlertAction* uninstallAction = [UIAlertAction actionWithTitle:@"Uninstall App" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action) + { + [self uninstallPressedForRowAtIndexPath:indexPath]; + [self deselectRow]; + }]; + [appSelectAlert addAction:uninstallAction]; - UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction* action) - { - [self deselectRow]; - }]; - [appSelectAlert addAction:cancelAction]; + UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction* action) + { + [self deselectRow]; + }]; + [appSelectAlert addAction:cancelAction]; appSelectAlert.popoverPresentationController.sourceView = tableView; appSelectAlert.popoverPresentationController.sourceRect = [tableView rectForRowAtIndexPath:indexPath]; - [self presentViewController:appSelectAlert animated:YES completion:nil]; + [self presentViewController:appSelectAlert animated:YES completion:nil]; } @end \ No newline at end of file diff --git a/Store/TSSceneDelegate.m b/Store/TSSceneDelegate.m index 59f8667..574f628 100644 --- a/Store/TSSceneDelegate.m +++ b/Store/TSSceneDelegate.m @@ -42,8 +42,10 @@ dispatch_async(dispatch_get_main_queue(), ^ { + NSLog(@"1"); [infoAlert dismissViewControllerAnimated:YES completion:^ { + NSLog(@"2"); if(ret != 0) { UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Install Error %d", ret] message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];