| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- //
- // FLEXLibrariesTableViewController.m
- // Flipboard
- //
- // Created by Ryan Olson on 2014-05-02.
- // Copyright (c) 2014 Flipboard. All rights reserved.
- //
- #import "FLEXLibrariesTableViewController.h"
- #import "FLEXUtility.h"
- #import "FLEXClassesTableViewController.h"
- #import "FLEXClassExplorerViewController.h"
- #import <objc/runtime.h>
- @interface FLEXLibrariesTableViewController ()
- @property (nonatomic) NSArray<NSString *> *imageNames;
- @property (nonatomic) NSArray<NSString *> *filteredImageNames;
- @property (nonatomic) Class foundClass;
- @end
- @implementation FLEXLibrariesTableViewController
- - (id)initWithStyle:(UITableViewStyle)style
- {
- self = [super initWithStyle:style];
- if (self) {
- [self loadImageNames];
- }
- return self;
- }
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
- self.showsSearchBar = YES;
- }
- #pragma mark - FLEXGlobalsEntry
- + (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row {
- return @"📚 System Libraries";
- }
- + (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row {
- FLEXLibrariesTableViewController *librariesViewController = [self new];
- librariesViewController.title = [self globalsEntryTitle:row];
- return librariesViewController;
- }
- #pragma mark - Binary Images
- - (void)loadImageNames
- {
- unsigned int imageNamesCount = 0;
- const char **imageNames = objc_copyImageNames(&imageNamesCount);
- if (imageNames) {
- NSMutableArray<NSString *> *imageNameStrings = [NSMutableArray array];
- NSString *appImageName = [FLEXUtility applicationImageName];
- for (unsigned int i = 0; i < imageNamesCount; i++) {
- const char *imageName = imageNames[i];
- NSString *imageNameString = [NSString stringWithUTF8String:imageName];
- // Skip the app's image. We're just showing system libraries and frameworks.
- if (![imageNameString isEqual:appImageName]) {
- [imageNameStrings addObject:imageNameString];
- }
- }
-
- // Sort alphabetically
- self.imageNames = [imageNameStrings sortedArrayWithOptions:0 usingComparator:^NSComparisonResult(NSString *name1, NSString *name2) {
- NSString *shortName1 = [self shortNameForImageName:name1];
- NSString *shortName2 = [self shortNameForImageName:name2];
- return [shortName1 caseInsensitiveCompare:shortName2];
- }];
-
- free(imageNames);
- }
- }
- - (NSString *)shortNameForImageName:(NSString *)imageName
- {
- NSArray<NSString *> *components = [imageName componentsSeparatedByString:@"/"];
- if (components.count >= 2) {
- return [NSString stringWithFormat:@"%@/%@", components[components.count - 2], components[components.count - 1]];
- }
- return imageName.lastPathComponent;
- }
- - (void)setImageNames:(NSArray<NSString *> *)imageNames
- {
- if (![_imageNames isEqual:imageNames]) {
- _imageNames = imageNames;
- self.filteredImageNames = imageNames;
- }
- }
- #pragma mark - Filtering
- - (void)updateSearchResults:(NSString *)searchText
- {
- if (searchText.length) {
- NSPredicate *searchPredicate = [NSPredicate predicateWithBlock:^BOOL(NSString *evaluatedObject, NSDictionary<NSString *, id> *bindings) {
- BOOL matches = NO;
- NSString *shortName = [self shortNameForImageName:evaluatedObject];
- if ([shortName rangeOfString:searchText options:NSCaseInsensitiveSearch].length > 0) {
- matches = YES;
- }
- return matches;
- }];
- self.filteredImageNames = [self.imageNames filteredArrayUsingPredicate:searchPredicate];
- } else {
- self.filteredImageNames = self.imageNames;
- }
-
- self.foundClass = NSClassFromString(searchText);
- [self.tableView reloadData];
- }
- #pragma mark - Table View Data Source
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
- {
- return 1;
- }
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- {
- return self.filteredImageNames.count + (self.foundClass ? 1 : 0);
- }
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- static NSString *cellIdentifier = @"Cell";
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
- if (!cell) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
- cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
- cell.textLabel.font = [FLEXUtility defaultTableViewCellLabelFont];
- }
-
- NSString *executablePath;
- if (self.foundClass) {
- if (indexPath.row == 0) {
- cell.textLabel.text = [NSString stringWithFormat:@"Class \"%@\"", self.searchText];
- return cell;
- } else {
- executablePath = self.filteredImageNames[indexPath.row-1];
- }
- } else {
- executablePath = self.filteredImageNames[indexPath.row];
- }
-
- cell.textLabel.text = [self shortNameForImageName:executablePath];
- return cell;
- }
- #pragma mark - Table View Delegate
- - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- {
- if (indexPath.row == 0 && self.foundClass) {
- FLEXClassExplorerViewController *objectExplorer = [FLEXClassExplorerViewController new];
- objectExplorer.object = self.foundClass;
- [self.navigationController pushViewController:objectExplorer animated:YES];
- } else {
- FLEXClassesTableViewController *classesViewController = [FLEXClassesTableViewController new];
- classesViewController.binaryImageName = self.filteredImageNames[self.foundClass ? indexPath.row-1 : indexPath.row];
- [self.navigationController pushViewController:classesViewController animated:YES];
- }
- }
- @end
|