FLEXNetworkHistoryTableViewController.m 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. //
  2. // FLEXNetworkHistoryTableViewController.m
  3. // Flipboard
  4. //
  5. // Created by Ryan Olson on 2/8/15.
  6. // Copyright (c) 2015 Flipboard. All rights reserved.
  7. //
  8. #import "FLEXNetworkHistoryTableViewController.h"
  9. #import "FLEXNetworkTransaction.h"
  10. #import "FLEXNetworkTransactionTableViewCell.h"
  11. #import "FLEXNetworkRecorder.h"
  12. #import "FLEXNetworkTransactionDetailTableViewController.h"
  13. @interface FLEXNetworkHistoryTableViewController () <UISearchDisplayDelegate>
  14. /// Backing model
  15. @property (nonatomic, copy) NSArray *networkTransactions;
  16. @property (nonatomic, copy) NSArray *filteredNetworkTransactions;
  17. @property (nonatomic, strong) UISearchDisplayController *searchController;
  18. @end
  19. @implementation FLEXNetworkHistoryTableViewController
  20. - (instancetype)initWithStyle:(UITableViewStyle)style
  21. {
  22. self = [super initWithStyle:style];
  23. if (self) {
  24. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNewTransactionRecordedNotification:) name:kFLEXNetworkRecorderNewTransactionNotification object:nil];
  25. self.title = @"📡 Network";
  26. }
  27. return self;
  28. }
  29. - (void)dealloc
  30. {
  31. [[NSNotificationCenter defaultCenter] removeObserver:self];
  32. }
  33. - (void)viewDidLoad
  34. {
  35. [super viewDidLoad];
  36. [self.tableView registerClass:[FLEXNetworkTransactionTableViewCell class] forCellReuseIdentifier:kFLEXNetworkTransactionCellIdentifier];
  37. self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  38. self.tableView.rowHeight = [FLEXNetworkTransactionTableViewCell preferredCellHeight];
  39. UISearchBar *searchBar = [[UISearchBar alloc] init];
  40. [searchBar sizeToFit];
  41. self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
  42. self.searchController.delegate = self;
  43. self.searchController.searchResultsDataSource = self;
  44. self.searchController.searchResultsDelegate = self;
  45. [self.searchController.searchResultsTableView registerClass:[FLEXNetworkTransactionTableViewCell class] forCellReuseIdentifier:kFLEXNetworkTransactionCellIdentifier];
  46. self.searchController.searchResultsTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  47. self.searchController.searchResultsTableView.rowHeight = [FLEXNetworkTransactionTableViewCell preferredCellHeight];
  48. self.tableView.tableHeaderView = self.searchController.searchBar;
  49. [self updateTransactions];
  50. }
  51. - (void)updateTransactions
  52. {
  53. self.networkTransactions = [[FLEXNetworkRecorder defaultRecorder] networkTransactions];
  54. }
  55. - (void)handleNewTransactionRecordedNotification:(NSNotification *)notification
  56. {
  57. // Note that these notifications may be posted from a background thread.
  58. dispatch_async(dispatch_get_main_queue(), ^{
  59. [self updateTransactions];
  60. [self.tableView reloadData];
  61. });
  62. }
  63. #pragma mark - Table view data source
  64. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  65. {
  66. return 1;
  67. }
  68. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  69. {
  70. NSInteger numberOfRows = 0;
  71. if (tableView == self.tableView) {
  72. numberOfRows = [self.networkTransactions count];
  73. } else if (tableView == self.searchController.searchResultsTableView) {
  74. numberOfRows = [self.filteredNetworkTransactions count];
  75. }
  76. return numberOfRows;
  77. }
  78. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  79. {
  80. FLEXNetworkTransactionTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kFLEXNetworkTransactionCellIdentifier forIndexPath:indexPath];
  81. cell.transaction = [self transactionAtIndexPath:indexPath inTableView:tableView];
  82. if (indexPath.row % 2 == 0) {
  83. cell.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0];
  84. } else {
  85. cell.backgroundColor = [UIColor whiteColor];
  86. }
  87. return cell;
  88. }
  89. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  90. {
  91. FLEXNetworkTransactionDetailTableViewController *detailViewController = [[FLEXNetworkTransactionDetailTableViewController alloc] init];
  92. detailViewController.transaction = [self transactionAtIndexPath:indexPath inTableView:tableView];
  93. [self.navigationController pushViewController:detailViewController animated:YES];
  94. }
  95. - (FLEXNetworkTransaction *)transactionAtIndexPath:(NSIndexPath *)indexPath inTableView:(UITableView *)tableView
  96. {
  97. FLEXNetworkTransaction *transaction = nil;
  98. if (tableView == self.tableView) {
  99. transaction = [self.networkTransactions objectAtIndex:indexPath.row];
  100. } else if (tableView == self.searchController.searchResultsTableView) {
  101. transaction = [self.filteredNetworkTransactions objectAtIndex:indexPath.row];
  102. }
  103. return transaction;
  104. }
  105. #pragma mark - Search display delegate
  106. - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
  107. {
  108. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  109. NSArray *filteredNetworkTransactions = [self.networkTransactions filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(FLEXNetworkTransaction *transaction, NSDictionary *bindings) {
  110. return [[transaction.request.URL absoluteString] rangeOfString:searchString options:NSCaseInsensitiveSearch].length > 0;
  111. }]];
  112. dispatch_async(dispatch_get_main_queue(), ^{
  113. if ([self.searchDisplayController.searchBar.text isEqual:searchString]) {
  114. self.filteredNetworkTransactions = filteredNetworkTransactions;
  115. [self.searchDisplayController.searchResultsTableView reloadData];
  116. }
  117. });
  118. });
  119. // Reload done after the data is filtered asynchronously
  120. return NO;
  121. }
  122. @end