FLEXClassesTableViewController.m 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //
  2. // FLEXClassesTableViewController.m
  3. // Flipboard
  4. //
  5. // Created by Ryan Olson on 2014-05-03.
  6. // Copyright (c) 2014 Flipboard. All rights reserved.
  7. //
  8. #import "FLEXClassesTableViewController.h"
  9. #import "FLEXObjectExplorerViewController.h"
  10. #import "FLEXObjectExplorerFactory.h"
  11. #import "FLEXUtility.h"
  12. #import <objc/runtime.h>
  13. @interface FLEXClassesTableViewController ()
  14. @property (nonatomic) NSArray<NSString *> *classNames;
  15. @property (nonatomic) NSArray<NSString *> *filteredClassNames;
  16. @end
  17. @implementation FLEXClassesTableViewController
  18. - (void)viewDidLoad
  19. {
  20. [super viewDidLoad];
  21. self.showsSearchBar = YES;
  22. }
  23. - (void)setBinaryImageName:(NSString *)binaryImageName
  24. {
  25. if (![_binaryImageName isEqual:binaryImageName]) {
  26. _binaryImageName = binaryImageName;
  27. [self loadClassNames];
  28. [self updateTitle];
  29. }
  30. }
  31. - (void)setClassNames:(NSArray<NSString *> *)classNames
  32. {
  33. _classNames = classNames;
  34. self.filteredClassNames = classNames;
  35. }
  36. - (void)loadClassNames
  37. {
  38. unsigned int classNamesCount = 0;
  39. const char **classNames = objc_copyClassNamesForImage(self.binaryImageName.UTF8String, &classNamesCount);
  40. if (classNames) {
  41. NSMutableArray<NSString *> *classNameStrings = [NSMutableArray array];
  42. for (unsigned int i = 0; i < classNamesCount; i++) {
  43. const char *className = classNames[i];
  44. NSString *classNameString = [NSString stringWithUTF8String:className];
  45. [classNameStrings addObject:classNameString];
  46. }
  47. self.classNames = [classNameStrings sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
  48. free(classNames);
  49. }
  50. }
  51. - (void)updateTitle
  52. {
  53. NSString *shortImageName = self.binaryImageName.lastPathComponent;
  54. self.title = [NSString stringWithFormat:@"%@ Classes (%lu)", shortImageName, (unsigned long)self.filteredClassNames.count];
  55. }
  56. #pragma mark - FLEXGlobalsEntry
  57. + (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row {
  58. return [NSString stringWithFormat:@"📕 %@ Classes", [FLEXUtility applicationName]];
  59. }
  60. + (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row {
  61. FLEXClassesTableViewController *classesViewController = [self new];
  62. classesViewController.binaryImageName = [FLEXUtility applicationImageName];
  63. return classesViewController;
  64. }
  65. #pragma mark - Search bar
  66. - (void)updateSearchResults:(NSString *)searchText
  67. {
  68. if (searchText.length > 0) {
  69. NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", searchText];
  70. self.filteredClassNames = [self.classNames filteredArrayUsingPredicate:searchPredicate];
  71. } else {
  72. self.filteredClassNames = self.classNames;
  73. }
  74. [self updateTitle];
  75. [self.tableView reloadData];
  76. }
  77. #pragma mark - Table View Data Source
  78. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  79. {
  80. return 1;
  81. }
  82. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  83. {
  84. return self.filteredClassNames.count;
  85. }
  86. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  87. {
  88. static NSString *CellIdentifier = @"Cell";
  89. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  90. if (!cell) {
  91. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
  92. cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
  93. cell.textLabel.font = [FLEXUtility defaultTableViewCellLabelFont];
  94. }
  95. cell.textLabel.text = self.filteredClassNames[indexPath.row];
  96. return cell;
  97. }
  98. #pragma mark - Table View Delegate
  99. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  100. {
  101. NSString *className = self.filteredClassNames[indexPath.row];
  102. Class selectedClass = objc_getClass(className.UTF8String);
  103. FLEXObjectExplorerViewController *objectExplorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:selectedClass];
  104. [self.navigationController pushViewController:objectExplorer animated:YES];
  105. }
  106. @end