You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
4.3 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  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, copy) NSArray<NSString *> *classNames;
  15. @property (nonatomic, copy) NSArray<NSString *> *filteredClassNames;
  16. @property (nonatomic, copy) NSString *binaryImageName;
  17. @end
  18. @implementation FLEXClassesTableViewController
  19. #pragma mark - Initialization
  20. + (instancetype)binaryImageName:(NSString *)binaryImageName
  21. {
  22. return [[self alloc] initWithBinaryImageName:binaryImageName];
  23. }
  24. - (id)initWithBinaryImageName:(NSString *)binaryImageName
  25. {
  26. NSParameterAssert(binaryImageName);
  27. self = [super init];
  28. if (self) {
  29. self.binaryImageName = binaryImageName;
  30. [self loadClassNames];
  31. }
  32. return self;
  33. }
  34. #pragma mark - Internal
  35. - (void)viewDidLoad
  36. {
  37. [super viewDidLoad];
  38. self.showsSearchBar = YES;
  39. [self updateTitle];
  40. }
  41. - (void)updateTitle
  42. {
  43. NSString *shortImageName = self.binaryImageName.lastPathComponent;
  44. self.title = [NSString stringWithFormat:@"%@ Classes (%lu)",
  45. shortImageName, (unsigned long)self.filteredClassNames.count
  46. ];
  47. }
  48. - (void)setClassNames:(NSArray<NSString *> *)classNames
  49. {
  50. _classNames = self.filteredClassNames = classNames.copy;
  51. }
  52. - (void)loadClassNames
  53. {
  54. unsigned int classNamesCount = 0;
  55. const char **classNames = objc_copyClassNamesForImage(self.binaryImageName.UTF8String, &classNamesCount);
  56. if (classNames) {
  57. NSMutableArray<NSString *> *classNameStrings = [NSMutableArray array];
  58. for (unsigned int i = 0; i < classNamesCount; i++) {
  59. const char *className = classNames[i];
  60. NSString *classNameString = [NSString stringWithUTF8String:className];
  61. [classNameStrings addObject:classNameString];
  62. }
  63. self.classNames = [classNameStrings sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
  64. free(classNames);
  65. }
  66. }
  67. #pragma mark - FLEXGlobalsEntry
  68. + (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row {
  69. return [NSString stringWithFormat:@"📕 %@ Classes", [FLEXUtility applicationName]];
  70. }
  71. + (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row {
  72. return [self binaryImageName:[FLEXUtility applicationImageName]];
  73. }
  74. #pragma mark - Search bar
  75. - (void)updateSearchResults:(NSString *)searchText
  76. {
  77. if (searchText.length > 0) {
  78. NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", searchText];
  79. self.filteredClassNames = [self.classNames filteredArrayUsingPredicate:searchPredicate].reverseObjectEnumerator.allObjects;
  80. } else {
  81. self.filteredClassNames = self.classNames;
  82. }
  83. [self updateTitle];
  84. [self.tableView reloadData];
  85. }
  86. #pragma mark - Table View Data Source
  87. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  88. {
  89. return 1;
  90. }
  91. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  92. {
  93. return self.filteredClassNames.count;
  94. }
  95. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  96. {
  97. static NSString *CellIdentifier = @"Cell";
  98. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  99. if (!cell) {
  100. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
  101. cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
  102. cell.textLabel.font = [FLEXUtility defaultTableViewCellLabelFont];
  103. }
  104. cell.textLabel.text = self.filteredClassNames[indexPath.row];
  105. return cell;
  106. }
  107. #pragma mark - Table View Delegate
  108. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  109. {
  110. NSString *className = self.filteredClassNames[indexPath.row];
  111. Class selectedClass = objc_getClass(className.UTF8String);
  112. FLEXObjectExplorerViewController *objectExplorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:selectedClass];
  113. [self.navigationController pushViewController:objectExplorer animated:YES];
  114. }
  115. @end