Просмотр исходного кода

Clean up FLEXNetworkRecorder

Network history will prompt to enable the monitor on tap
Tanner Bennett лет назад: 6
Родитель
Сommit
8533689ca7

+ 50 - 18
Classes/Network/FLEXNetworkMITMViewController.m

@@ -15,6 +15,7 @@
 #import "FLEXNetworkTransactionTableViewCell.h"
 #import "FLEXNetworkTransactionTableViewCell.h"
 #import "FLEXNetworkTransactionDetailTableViewController.h"
 #import "FLEXNetworkTransactionDetailTableViewController.h"
 #import "FLEXNetworkSettingsTableViewController.h"
 #import "FLEXNetworkSettingsTableViewController.h"
+#import "FLEXGlobalsViewController.h"
 #import "UIBarButtonItem+FLEX.h"
 #import "UIBarButtonItem+FLEX.h"
 #import "FLEXResources.h"
 #import "FLEXResources.h"
 
 
@@ -36,10 +37,15 @@
 
 
 #pragma mark - Lifecycle
 #pragma mark - Lifecycle
 
 
+- (id)init {
+    return [self initWithStyle:UITableViewStylePlain];
+}
+
 - (void)viewDidLoad {
 - (void)viewDidLoad {
     [super viewDidLoad];
     [super viewDidLoad];
 
 
     self.showsSearchBar = YES;
     self.showsSearchBar = YES;
+    self.showSearchBarInitially = NO;
     
     
     [self addToolbarItems:@[[UIBarButtonItem
     [self addToolbarItems:@[[UIBarButtonItem
         itemWithImage:FLEXResources.gearIcon
         itemWithImage:FLEXResources.gearIcon
@@ -115,7 +121,7 @@
 #pragma mark Transactions
 #pragma mark Transactions
 
 
 - (void)updateTransactions {
 - (void)updateTransactions {
-    self.networkTransactions = [[FLEXNetworkRecorder defaultRecorder] networkTransactions];
+    self.networkTransactions = [FLEXNetworkRecorder.defaultRecorder networkTransactions];
 }
 }
 
 
 - (void)setNetworkTransactions:(NSArray<FLEXNetworkTransaction *> *)networkTransactions {
 - (void)setNetworkTransactions:(NSArray<FLEXNetworkTransaction *> *)networkTransactions {
@@ -163,24 +169,23 @@
 }
 }
 
 
 - (NSString *)headerText {
 - (NSString *)headerText {
-    NSString *headerText = nil;
-    if (FLEXNetworkObserver.isEnabled) {
-        long long bytesReceived = 0;
-        NSInteger totalRequests = 0;
-        if (self.searchController.isActive) {
-            bytesReceived = self.filteredBytesReceived;
-            totalRequests = self.filteredNetworkTransactions.count;
-        } else {
-            bytesReceived = self.bytesReceived;
-            totalRequests = self.networkTransactions.count;
-        }
-        NSString *byteCountText = [NSByteCountFormatter stringFromByteCount:bytesReceived countStyle:NSByteCountFormatterCountStyleBinary];
-        NSString *requestsText = totalRequests == 1 ? @"Request" : @"Requests";
-        headerText = [NSString stringWithFormat:@"%ld %@ (%@ received)", (long)totalRequests, requestsText, byteCountText];
+    long long bytesReceived = 0;
+    NSInteger totalRequests = 0;
+    if (self.searchController.isActive) {
+        bytesReceived = self.filteredBytesReceived;
+        totalRequests = self.filteredNetworkTransactions.count;
     } else {
     } else {
-        headerText = @"⚠️  Debugging Disabled (Enable in Settings)";
+        bytesReceived = self.bytesReceived;
+        totalRequests = self.networkTransactions.count;
     }
     }
-    return headerText;
+    
+    NSString *byteCountText = [NSByteCountFormatter
+        stringFromByteCount:bytesReceived countStyle:NSByteCountFormatterCountStyleBinary
+    ];
+    NSString *requestsText = totalRequests == 1 ? @"Request" : @"Requests";
+    return [NSString stringWithFormat:@"%@ %@ (%@ received)",
+        @(totalRequests), requestsText, byteCountText
+    ];
 }
 }
 
 
 
 
@@ -190,8 +195,33 @@
     return @"📡  Network History";
     return @"📡  Network History";
 }
 }
 
 
++ (FLEXGlobalsTableViewControllerRowAction)globalsEntryRowAction:(FLEXGlobalsRow)row {
+    return ^(FLEXGlobalsViewController *host) {
+        if (FLEXNetworkObserver.isEnabled) {
+            [host.navigationController pushViewController:[
+                self globalsEntryViewController:row
+            ] animated:YES];
+        } else {
+            [FLEXAlert makeAlert:^(FLEXAlert *make) {
+                make.title(@"Network Monitor Disabled");
+                make.message(@"You must enable network monitoring to proceed.");
+                
+                make.button(@"Turn On").handler(^(NSArray<NSString *> *strings) {
+                    FLEXNetworkObserver.enabled = YES;
+                    [host.navigationController pushViewController:[
+                        self globalsEntryViewController:row
+                    ] animated:YES];
+                }).cancelStyle();
+                make.button(@"Dismiss");
+            } showFrom:host];
+        }
+    };
+}
+
 + (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row {
 + (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row {
-    return [self new];
+    UIViewController *controller = [self new];
+    controller.title = [self globalsEntryTitle:row];
+    return controller;
 }
 }
 
 
 
 
@@ -207,6 +237,7 @@
         self.pendingReload = YES;
         self.pendingReload = YES;
         return;
         return;
     }
     }
+    
     // Let the previous row insert animation finish before starting a new one to avoid stomping.
     // Let the previous row insert animation finish before starting a new one to avoid stomping.
     // We'll try calling the method again when the insertion completes, and we properly no-op if there haven't been changes.
     // We'll try calling the method again when the insertion completes, and we properly no-op if there haven't been changes.
     if (self.rowInsertInProgress) {
     if (self.rowInsertInProgress) {
@@ -390,6 +421,7 @@
     }
     }
 }
 }
 
 
+
 #pragma mark UISearchControllerDelegate
 #pragma mark UISearchControllerDelegate
 
 
 - (void)willPresentSearchController:(UISearchController *)searchController {
 - (void)willPresentSearchController:(UISearchController *)searchController {

+ 57 - 38
Classes/Network/FLEXNetworkRecorder.m

@@ -34,19 +34,20 @@ NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.r
     self = [super init];
     self = [super init];
     if (self) {
     if (self) {
         self.responseCache = [NSCache new];
         self.responseCache = [NSCache new];
-        NSUInteger responseCacheLimit = [[[NSUserDefaults standardUserDefaults] objectForKey:kFLEXNetworkRecorderResponseCacheLimitDefaultsKey] unsignedIntegerValue];
-        if (responseCacheLimit) {
-            [self.responseCache setTotalCostLimit:responseCacheLimit];
-        } else {
-            // Default to 25 MB max. The cache will purge earlier if there is memory pressure.
-            [self.responseCache setTotalCostLimit:25 * 1024 * 1024];
-        }
+        NSUInteger responseCacheLimit = [[NSUserDefaults.standardUserDefaults
+            objectForKey:kFLEXNetworkRecorderResponseCacheLimitDefaultsKey] unsignedIntegerValue
+        ];
+        // Default to 25 MB max. The cache will purge earlier if there is memory pressure.
+        self.responseCache.totalCostLimit = responseCacheLimit ?: 25 * 1024 * 1024;
+        [self.responseCache setTotalCostLimit:responseCacheLimit];
+        
         self.orderedTransactions = [NSMutableArray array];
         self.orderedTransactions = [NSMutableArray array];
         self.networkTransactionsForRequestIdentifiers = [NSMutableDictionary dictionary];
         self.networkTransactionsForRequestIdentifiers = [NSMutableDictionary dictionary];
 
 
         // Serial queue used because we use mutable objects that are not thread safe
         // Serial queue used because we use mutable objects that are not thread safe
         self.queue = dispatch_queue_create("com.flex.FLEXNetworkRecorder", DISPATCH_QUEUE_SERIAL);
         self.queue = dispatch_queue_create("com.flex.FLEXNetworkRecorder", DISPATCH_QUEUE_SERIAL);
     }
     }
+    
     return self;
     return self;
 }
 }
 
 
@@ -56,24 +57,28 @@ NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.r
     dispatch_once(&onceToken, ^{
     dispatch_once(&onceToken, ^{
         defaultRecorder = [self new];
         defaultRecorder = [self new];
     });
     });
+    
     return defaultRecorder;
     return defaultRecorder;
 }
 }
 
 
 #pragma mark - Public Data Access
 #pragma mark - Public Data Access
 
 
 - (NSUInteger)responseCacheByteLimit {
 - (NSUInteger)responseCacheByteLimit {
-    return [self.responseCache totalCostLimit];
+    return self.responseCache.totalCostLimit;
 }
 }
 
 
 - (void)setResponseCacheByteLimit:(NSUInteger)responseCacheByteLimit {
 - (void)setResponseCacheByteLimit:(NSUInteger)responseCacheByteLimit {
-    [self.responseCache setTotalCostLimit:responseCacheByteLimit];
-    [[NSUserDefaults standardUserDefaults] setObject:@(responseCacheByteLimit) forKey:kFLEXNetworkRecorderResponseCacheLimitDefaultsKey];
+    self.responseCache.totalCostLimit = responseCacheByteLimit;
+    [NSUserDefaults.standardUserDefaults
+        setObject:@(responseCacheByteLimit)
+        forKey:kFLEXNetworkRecorderResponseCacheLimitDefaultsKey
+    ];
 }
 }
 
 
 - (NSArray<FLEXNetworkTransaction *> *)networkTransactions {
 - (NSArray<FLEXNetworkTransaction *> *)networkTransactions {
     __block NSArray<FLEXNetworkTransaction *> *transactions = nil;
     __block NSArray<FLEXNetworkTransaction *> *transactions = nil;
     dispatch_sync(self.queue, ^{
     dispatch_sync(self.queue, ^{
-        transactions = [self.orderedTransactions copy];
+        transactions = self.orderedTransactions.copy;
     });
     });
     return transactions;
     return transactions;
 }
 }
@@ -87,22 +92,24 @@ NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.r
         [self.responseCache removeAllObjects];
         [self.responseCache removeAllObjects];
         [self.orderedTransactions removeAllObjects];
         [self.orderedTransactions removeAllObjects];
         [self.networkTransactionsForRequestIdentifiers removeAllObjects];
         [self.networkTransactionsForRequestIdentifiers removeAllObjects];
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [NSNotificationCenter.defaultCenter postNotificationName:kFLEXNetworkRecorderTransactionsClearedNotification object:self];
-        });
+        
+        [self notify:kFLEXNetworkRecorderTransactionsClearedNotification transaction:nil];
     });
     });
 }
 }
 
 
 #pragma mark - Network Events
 #pragma mark - Network Events
 
 
-- (void)recordRequestWillBeSentWithRequestID:(NSString *)requestID request:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse {
+- (void)recordRequestWillBeSentWithRequestID:(NSString *)requestID
+                                     request:(NSURLRequest *)request
+                            redirectResponse:(NSURLResponse *)redirectResponse {
     for (NSString *host in self.hostBlacklist) {
     for (NSString *host in self.hostBlacklist) {
         if ([request.URL.host hasSuffix:host]) {
         if ([request.URL.host hasSuffix:host]) {
             return;
             return;
         }
         }
     }
     }
     
     
-    NSDate *startDate = [NSDate date];
+    // Before async block to stay accurate
+    NSDate *startDate = NSDate.date;
 
 
     if (redirectResponse) {
     if (redirectResponse) {
         [self recordResponseReceivedWithRequestID:requestID response:redirectResponse];
         [self recordResponseReceivedWithRequestID:requestID response:redirectResponse];
@@ -124,13 +131,15 @@ NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.r
 }
 }
 
 
 - (void)recordResponseReceivedWithRequestID:(NSString *)requestID response:(NSURLResponse *)response {
 - (void)recordResponseReceivedWithRequestID:(NSString *)requestID response:(NSURLResponse *)response {
-    NSDate *responseDate = [NSDate date];
+    // Before async block to stay accurate
+    NSDate *responseDate = NSDate.date;
 
 
     dispatch_async(self.queue, ^{
     dispatch_async(self.queue, ^{
         FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID];
         FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID];
         if (!transaction) {
         if (!transaction) {
             return;
             return;
         }
         }
+        
         transaction.response = response;
         transaction.response = response;
         transaction.transactionState = FLEXNetworkTransactionStateReceivingData;
         transaction.transactionState = FLEXNetworkTransactionStateReceivingData;
         transaction.latency = -[transaction.startTime timeIntervalSinceDate:responseDate];
         transaction.latency = -[transaction.startTime timeIntervalSinceDate:responseDate];
@@ -145,8 +154,8 @@ NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.r
         if (!transaction) {
         if (!transaction) {
             return;
             return;
         }
         }
+        
         transaction.receivedDataLength += dataLength;
         transaction.receivedDataLength += dataLength;
-
         [self postUpdateNotificationForTransaction:transaction];
         [self postUpdateNotificationForTransaction:transaction];
     });
     });
 }
 }
@@ -159,6 +168,7 @@ NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.r
         if (!transaction) {
         if (!transaction) {
             return;
             return;
         }
         }
+        
         transaction.transactionState = FLEXNetworkTransactionStateFinished;
         transaction.transactionState = FLEXNetworkTransactionStateFinished;
         transaction.duration = -[transaction.startTime timeIntervalSinceDate:finishedDate];
         transaction.duration = -[transaction.startTime timeIntervalSinceDate:finishedDate];
 
 
@@ -179,29 +189,32 @@ NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.r
             // Thumbnail image previews on a separate background queue
             // Thumbnail image previews on a separate background queue
             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                 NSInteger maxPixelDimension = UIScreen.mainScreen.scale * 32.0;
                 NSInteger maxPixelDimension = UIScreen.mainScreen.scale * 32.0;
-                transaction.responseThumbnail = [FLEXUtility thumbnailedImageWithMaxPixelDimension:maxPixelDimension fromImageData:responseBody];
+                transaction.responseThumbnail = [FLEXUtility
+                    thumbnailedImageWithMaxPixelDimension:maxPixelDimension
+                    fromImageData:responseBody
+                ];
                 [self postUpdateNotificationForTransaction:transaction];
                 [self postUpdateNotificationForTransaction:transaction];
             });
             });
         } else if ([mimeType isEqual:@"application/json"]) {
         } else if ([mimeType isEqual:@"application/json"]) {
-            transaction.responseThumbnail = [FLEXResources jsonIcon];
+            transaction.responseThumbnail = FLEXResources.jsonIcon;
         } else if ([mimeType isEqual:@"text/plain"]){
         } else if ([mimeType isEqual:@"text/plain"]){
-            transaction.responseThumbnail = [FLEXResources textPlainIcon];
+            transaction.responseThumbnail = FLEXResources.textPlainIcon;
         } else if ([mimeType isEqual:@"text/html"]) {
         } else if ([mimeType isEqual:@"text/html"]) {
-            transaction.responseThumbnail = [FLEXResources htmlIcon];
+            transaction.responseThumbnail = FLEXResources.htmlIcon;
         } else if ([mimeType isEqual:@"application/x-plist"]) {
         } else if ([mimeType isEqual:@"application/x-plist"]) {
-            transaction.responseThumbnail = [FLEXResources plistIcon];
+            transaction.responseThumbnail = FLEXResources.plistIcon;
         } else if ([mimeType isEqual:@"application/octet-stream"] || [mimeType isEqual:@"application/binary"]) {
         } else if ([mimeType isEqual:@"application/octet-stream"] || [mimeType isEqual:@"application/binary"]) {
-            transaction.responseThumbnail = [FLEXResources binaryIcon];
-        } else if ([mimeType rangeOfString:@"javascript"].length > 0) {
-            transaction.responseThumbnail = [FLEXResources jsIcon];
-        } else if ([mimeType rangeOfString:@"xml"].length > 0) {
-            transaction.responseThumbnail = [FLEXResources xmlIcon];
+            transaction.responseThumbnail = FLEXResources.binaryIcon;
+        } else if ([mimeType containsString:@"javascript"]) {
+            transaction.responseThumbnail = FLEXResources.jsIcon;
+        } else if ([mimeType containsString:@"xml"]) {
+            transaction.responseThumbnail = FLEXResources.xmlIcon;
         } else if ([mimeType hasPrefix:@"audio"]) {
         } else if ([mimeType hasPrefix:@"audio"]) {
-            transaction.responseThumbnail = [FLEXResources audioIcon];
+            transaction.responseThumbnail = FLEXResources.audioIcon;
         } else if ([mimeType hasPrefix:@"video"]) {
         } else if ([mimeType hasPrefix:@"video"]) {
-            transaction.responseThumbnail = [FLEXResources videoIcon];
+            transaction.responseThumbnail = FLEXResources.videoIcon;
         } else if ([mimeType hasPrefix:@"text"]) {
         } else if ([mimeType hasPrefix:@"text"]) {
-            transaction.responseThumbnail = [FLEXResources textIcon];
+            transaction.responseThumbnail = FLEXResources.textIcon;
         }
         }
         
         
         [self postUpdateNotificationForTransaction:transaction];
         [self postUpdateNotificationForTransaction:transaction];
@@ -214,6 +227,7 @@ NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.r
         if (!transaction) {
         if (!transaction) {
             return;
             return;
         }
         }
+        
         transaction.transactionState = FLEXNetworkTransactionStateFailed;
         transaction.transactionState = FLEXNetworkTransactionStateFailed;
         transaction.duration = -[transaction.startTime timeIntervalSinceNow];
         transaction.duration = -[transaction.startTime timeIntervalSinceNow];
         transaction.error = error;
         transaction.error = error;
@@ -228,8 +242,8 @@ NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.r
         if (!transaction) {
         if (!transaction) {
             return;
             return;
         }
         }
+        
         transaction.requestMechanism = mechanism;
         transaction.requestMechanism = mechanism;
-
         [self postUpdateNotificationForTransaction:transaction];
         [self postUpdateNotificationForTransaction:transaction];
     });
     });
 }
 }
@@ -237,16 +251,21 @@ NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.r
 #pragma mark Notification Posting
 #pragma mark Notification Posting
 
 
 - (void)postNewTransactionNotificationWithTransaction:(FLEXNetworkTransaction *)transaction {
 - (void)postNewTransactionNotificationWithTransaction:(FLEXNetworkTransaction *)transaction {
-    dispatch_async(dispatch_get_main_queue(), ^{
-        NSDictionary<NSString *, id> *userInfo = @{ kFLEXNetworkRecorderUserInfoTransactionKey : transaction };
-        [NSNotificationCenter.defaultCenter postNotificationName:kFLEXNetworkRecorderNewTransactionNotification object:self userInfo:userInfo];
-    });
+    [self notify:kFLEXNetworkRecorderNewTransactionNotification transaction:transaction];
 }
 }
 
 
 - (void)postUpdateNotificationForTransaction:(FLEXNetworkTransaction *)transaction {
 - (void)postUpdateNotificationForTransaction:(FLEXNetworkTransaction *)transaction {
+    [self notify:kFLEXNetworkRecorderTransactionUpdatedNotification transaction:transaction];
+}
+
+- (void)notify:(NSString *)name transaction:(FLEXNetworkTransaction *)transaction {
+    NSDictionary *userInfo = nil;
+    if (transaction) {
+        userInfo = @{ kFLEXNetworkRecorderUserInfoTransactionKey : transaction };
+    }
+    
     dispatch_async(dispatch_get_main_queue(), ^{
     dispatch_async(dispatch_get_main_queue(), ^{
-        NSDictionary<NSString *, id> *userInfo = @{ kFLEXNetworkRecorderUserInfoTransactionKey : transaction };
-        [NSNotificationCenter.defaultCenter postNotificationName:kFLEXNetworkRecorderTransactionUpdatedNotification object:self userInfo:userInfo];
+        [NSNotificationCenter.defaultCenter postNotificationName:name object:self userInfo:userInfo];
     });
     });
 }
 }
 
 

+ 3 - 4
Classes/Network/FLEXNetworkSettingsTableViewController.m

@@ -52,6 +52,7 @@
     self.cells = mutableCells;
     self.cells = mutableCells;
 }
 }
 
 
+
 #pragma mark - Settings Actions
 #pragma mark - Settings Actions
 
 
 - (void)networkDebuggingToggled:(UISwitch *)sender {
 - (void)networkDebuggingToggled:(UISwitch *)sender {
@@ -79,11 +80,8 @@
     self.popoverPresentationController.sourceRect = sender.bounds;
     self.popoverPresentationController.sourceRect = sender.bounds;
 }
 }
 
 
-#pragma mark - Table view data source
 
 
-- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
-    return 1;
-}
+#pragma mark - Table View Data Source
 
 
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     return self.cells.count;
     return self.cells.count;
@@ -93,6 +91,7 @@
     return self.cells[indexPath.row];
     return self.cells[indexPath.row];
 }
 }
 
 
+
 #pragma mark - Helpers
 #pragma mark - Helpers
 
 
 - (UITableViewCell *)switchCellWithTitle:(NSString *)title toggleAction:(SEL)toggleAction isOn:(BOOL)isOn {
 - (UITableViewCell *)switchCellWithTitle:(NSString *)title toggleAction:(SEL)toggleAction isOn:(BOOL)isOn {