Skip to content

Commit

Permalink
Adopt FLEXAlert
Browse files Browse the repository at this point in the history
- Add FLEXAlert, a builder-oriented UIAlertController wrapper
- Replace all uses of UIAlertController with FLEXAlert
- Moves some alert methods from FLEXUtility to FLEXAlert
  • Loading branch information
NSExceptional committed Aug 21, 2019
1 parent ca919a4 commit ac4c50b
Show file tree
Hide file tree
Showing 12 changed files with 402 additions and 105 deletions.
2 changes: 1 addition & 1 deletion Classes/Editing/FLEXMethodCallingViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ - (void)actionButtonPressed:(id)sender
id returnedObject = [FLEXRuntimeUtility performSelector:method_getName(self.method) onObject:self.target withArguments:arguments error:&error];

if (error) {
[FLEXUtility alert:@"Method Call Failed" message:[error localizedDescription] from:self];
[FLEXAlert showAlert:@"Method Call Failed" message:[error localizedDescription] from:self];
} else if (returnedObject) {
// For non-nil (or void) return types, push an explorer view controller to display the returned object
returnedObject = [FLEXRuntimeUtility potentiallyUnwrapBoxedPointer:returnedObject type:self.returnType];
Expand Down
2 changes: 1 addition & 1 deletion Classes/Editing/FLEXPropertyEditorViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ - (void)actionButtonPressed:(id)sender
NSError *error = nil;
[FLEXRuntimeUtility performSelector:setterSelector onObject:self.target withArguments:arguments error:&error];
if (error) {
[FLEXUtility alert:@"Property Setter Failed" message:[error localizedDescription] from:self];
[FLEXAlert showAlert:@"Property Setter Failed" message:[error localizedDescription] from:self];
self.firstInputView.inputValue = [FLEXRuntimeUtility valueForProperty:self.property onObject:self.target];
} else {
// If the setter was called without error, pop the view controller to indicate that and make the user's life easier.
Expand Down
52 changes: 22 additions & 30 deletions Classes/GlobalStateExplorers/FLEXAddressExplorerCoordinator.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,40 +28,32 @@ + (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row {

+ (FLEXGlobalsTableViewControllerRowAction)globalsEntryRowAction:(FLEXGlobalsRow)row {
return ^(FLEXGlobalsTableViewController *host) {

NSString *title = @"Explore Object at Address";
NSString *message = @"Paste a hexadecimal address below, starting with '0x'. "
"Use the unsafe option if you need to bypass pointer validation, "
"but know that it may crash the app if the address is invalid.";

UIAlertController *addressInput = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
void (^handler)(UIAlertAction *) = ^(UIAlertAction *action) {
if (action.style == UIAlertActionStyleCancel) {
[host deselectSelectedRow]; return;
}
NSString *address = addressInput.textFields.firstObject.text;
[host tryExploreAddress:address safely:action.style == UIAlertActionStyleDefault];
};
[addressInput addTextFieldWithConfigurationHandler:^(UITextField *textField) {
NSString *copied = UIPasteboard.generalPasteboard.string;
textField.placeholder = @"0x00000070deadbeef";
// Go ahead and paste our clipboard if we have an address copied
if ([copied hasPrefix:@"0x"]) {
textField.text = copied;
[textField selectAll:nil];
}
}];
[addressInput addAction:[UIAlertAction actionWithTitle:@"Explore"
style:UIAlertActionStyleDefault
handler:handler]];
[addressInput addAction:[UIAlertAction actionWithTitle:@"Unsafe Explore"
style:UIAlertActionStyleDestructive
handler:handler]];
[addressInput addAction:[UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:handler]];
[host presentViewController:addressInput animated:YES completion:nil];
[FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(title).message(message);
make.configuredTextField(^(UITextField *textField) {
NSString *copied = UIPasteboard.generalPasteboard.string;
textField.placeholder = @"0x00000070deadbeef";
// Go ahead and paste our clipboard if we have an address copied
if ([copied hasPrefix:@"0x"]) {
textField.text = copied;
[textField selectAll:nil];
}
});
make.button(@"Explore").handler(^(NSArray<NSString *> *strings) {
[host tryExploreAddress:strings.firstObject safely:YES];
});
make.button(@"Unsafe Explore").destructiveStyle().handler(^(NSArray *strings) {
[host tryExploreAddress:strings.firstObject safely:NO];
});
make.button(@"Cancel").cancelStyle();
} showFrom:host];

};
}

Expand Down Expand Up @@ -95,7 +87,7 @@ - (void)tryExploreAddress:(NSString *)addressString safely:(BOOL)safely {
FLEXObjectExplorerViewController *explorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:object];
[self.navigationController pushViewController:explorer animated:YES];
} else {
[FLEXUtility alert:@"Uh-oh" message:error from:self];
[FLEXAlert showAlert:@"Uh-oh" message:error from:self];
[self deselectSelectedRow];
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
UIImage *image = cell.imageView.image;

if (!stillExists) {
[FLEXUtility alert:@"File Not Found" message:@"The file at the specified path no longer exists." from:self];
[FLEXAlert showAlert:@"File Not Found" message:@"The file at the specified path no longer exists." from:self];
[self reloadDisplayedPaths];
return;
}
Expand All @@ -223,7 +223,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
} else {
NSData *fileData = [NSData dataWithContentsOfFile:fullPath];
if (!fileData.length) {
[FLEXUtility alert:@"Empty File" message:@"No data returned from the file." from:self];
[FLEXAlert showAlert:@"Empty File" message:@"No data returned from the file." from:self];
return;
}

Expand Down Expand Up @@ -321,24 +321,22 @@ - (void)fileBrowserRename:(UITableViewCell *)sender

BOOL stillExists = [NSFileManager.defaultManager fileExistsAtPath:self.path isDirectory:NULL];
if (stillExists) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Rename %@?", fullPath.lastPathComponent]
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = @"New file name";
textField.text = fullPath.lastPathComponent;
}];
__weak typeof(alert) weakAlert = alert;
[alert addAction:[UIAlertAction actionWithTitle:@"Rename" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *newFileName = weakAlert.textFields.firstObject.text;
NSString *newPath = [[fullPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFileName];
[NSFileManager.defaultManager moveItemAtPath:fullPath toPath:newPath error:NULL];
[self reloadDisplayedPaths];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
[FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title([NSString stringWithFormat:@"Rename %@?", fullPath.lastPathComponent]);
make.configuredTextField(^(UITextField *textField) {
textField.placeholder = @"New file name";
textField.text = fullPath.lastPathComponent;
});
make.button(@"Rename").handler(^(NSArray<NSString *> *strings) {
NSString *newFileName = strings.firstObject;
NSString *newPath = [fullPath.stringByDeletingLastPathComponent stringByAppendingPathComponent:newFileName];
[NSFileManager.defaultManager moveItemAtPath:fullPath toPath:newPath error:NULL];
[self reloadDisplayedPaths];
});
make.button(@"Cancel").cancelStyle();
} showFrom:self];
} else {
[FLEXUtility alert:@"File Removed" message:@"The file at the specified path no longer exists." from:self];
[FLEXAlert showAlert:@"File Removed" message:@"The file at the specified path no longer exists." from:self];
}
}

Expand All @@ -350,17 +348,20 @@ - (void)fileBrowserDelete:(UITableViewCell *)sender
BOOL isDirectory = NO;
BOOL stillExists = [NSFileManager.defaultManager fileExistsAtPath:fullPath isDirectory:&isDirectory];
if (stillExists) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Delete %@?", fullPath.lastPathComponent]
message:[NSString stringWithFormat:@"The %@ will be deleted. This operation cannot be undone", isDirectory ? @"directory" : @"file"]
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
[NSFileManager.defaultManager removeItemAtPath:fullPath error:NULL];
[self reloadDisplayedPaths];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
[FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(@"Confirm Deletion");
make.message([NSString stringWithFormat:
@"The %@ '%@' will be deleted. This operation cannot be undone",
(isDirectory ? @"directory" : @"file"), fullPath.lastPathComponent
]);
make.button(@"Delete").destructiveStyle().handler(^(NSArray<NSString *> *strings) {
[NSFileManager.defaultManager removeItemAtPath:fullPath error:NULL];
[self reloadDisplayedPaths];
});
make.button(@"Cancel").cancelStyle();
} showFrom:self];
} else {
[FLEXUtility alert:@"File Removed" message:@"The file at the specified path no longer exists." from:self];
[FLEXAlert showAlert:@"File Removed" message:@"The file at the specified path no longer exists." from:self];
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,15 @@ - (void)showLogSettings
NSString *body = @"In iOS 10 and up, ASL is gone. The OS Log API is much more limited. "
"To get as close to the old behavior as possible, logs must be collected manually at launch and stored.\n\n"
"Turn this feature on only when you need it.";

UIAlertController *settings = [UIAlertController alertControllerWithTitle:title message:body preferredStyle:UIAlertControllerStyleAlert];
[settings addAction:[UIAlertAction actionWithTitle:toggle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[[NSUserDefaults standardUserDefaults] setBool:!persistent forKey:kFLEXiOSPersistentOSLogKey];
logController.persistent = !persistent;
[logController.messages addObjectsFromArray:self.logMessages];
}]];
[settings addAction:[UIAlertAction actionWithTitle:@"Dismiss" style:UIAlertActionStyleCancel handler:nil]];

[self presentViewController:settings animated:YES completion:nil];

[FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(title).message(body).button(toggle).handler(^(NSArray<NSString *> *strings) {
[[NSUserDefaults standardUserDefaults] setBool:!persistent forKey:kFLEXiOSPersistentOSLogKey];
logController.persistent = !persistent;
[logController.messages addObjectsFromArray:self.logMessages];
});
make.button(@"Dismiss").cancelStyle();
} showFrom:self];
}

#pragma mark - FLEXGlobalsEntry
Expand Down
13 changes: 7 additions & 6 deletions Classes/Network/FLEXNetworkSettingsTableViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,15 @@ - (void)cacheLimitAdjusted:(UISlider *)sender

- (void)clearRequestsTapped:(UIButton *)sender
{
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Clear Recorded Requests" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
[[FLEXNetworkRecorder defaultRecorder] clearRecordedActivity];
}]];
[FLEXAlert makeSheet:^(FLEXAlert *make) {
make.button(@"Cancel").cancelStyle();
make.button(@"Clear Recorded Requests").destructiveStyle().handler(^(NSArray *strings) {
[[FLEXNetworkRecorder defaultRecorder] clearRecordedActivity];
});
} showFrom:self];

self.popoverPresentationController.sourceView = sender;
self.popoverPresentationController.sourceRect = sender.bounds;
[self presentViewController:actionSheet animated:YES completion:nil];
}

#pragma mark - Table view data source
Expand Down
52 changes: 30 additions & 22 deletions Classes/Network/FLEXNetworkTransactionDetailTableViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -259,21 +259,24 @@ + (FLEXNetworkDetailSection *)generalSectionForTransaction:(FLEXNetworkTransacti
FLEXNetworkDetailRow *postBodyRow = [FLEXNetworkDetailRow new];
postBodyRow.title = @"Request Body";
postBodyRow.detailText = @"tap to view";
postBodyRow.selectionFuture = ^UIViewController * (void){
postBodyRow.selectionFuture = ^UIViewController * () {
// Show the body if we can
NSString *contentType = [transaction.request valueForHTTPHeaderField:@"Content-Type"];
UIViewController *detailViewController = [self detailViewControllerForMIMEType:contentType data:[self postBodyDataForTransaction:transaction]];
if (detailViewController) {
detailViewController.title = @"Request Body";
return detailViewController;
}

NSString *alertMessage = [NSString stringWithFormat:@"FLEX does not have a viewer for request body data with MIME type: %@", [transaction.request valueForHTTPHeaderField:@"Content-Type"]];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Can't View Body Data"
message:alertMessage
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]];
return alert;
// We can't show the body, alert user
return [FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(@"Can't View HTTP Body Data");
make.message(@"FLEX does not have a viewer for request body data with MIME type: ");
make.message(contentType);
make.button(@"Dismiss").cancelStyle();
}];
};

[rows addObject:postBodyRow];
}

Expand All @@ -297,33 +300,38 @@ + (FLEXNetworkDetailSection *)generalSectionForTransaction:(FLEXNetworkTransacti
NSData *responseData = [[FLEXNetworkRecorder defaultRecorder] cachedResponseBodyForTransaction:transaction];
if (responseData.length > 0) {
responseBodyRow.detailText = @"tap to view";

// Avoid a long lived strong reference to the response data in case we need to purge it from the cache.
__weak NSData *weakResponseData = responseData;
responseBodyRow.selectionFuture = ^UIViewController * (void){
NSString *alertMessage = nil;
responseBodyRow.selectionFuture = ^UIViewController * () {

// Show the response if we can
NSString *contentType = transaction.response.MIMEType;
NSData *strongResponseData = weakResponseData;
if (strongResponseData) {
UIViewController *responseBodyDetailViewController = [self detailViewControllerForMIMEType:transaction.response.MIMEType data:strongResponseData];
if (responseBodyDetailViewController) {
responseBodyDetailViewController.title = @"Response";
return responseBodyDetailViewController;
UIViewController *bodyDetailController = [self detailViewControllerForMIMEType:contentType data:strongResponseData];
if (bodyDetailController) {
bodyDetailController.title = @"Response";
return bodyDetailController;
}

alertMessage = [NSString stringWithFormat:@"FLEX does not have a viewer for responses with MIME type: %@", transaction.response.MIMEType];
} else {
alertMessage = @"The response has been purged from the cache";
}

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Can't View Response"
message:alertMessage
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]];
return alert;
// We can't show the response, alert user
return [FLEXAlert makeAlert:^(FLEXAlert *make) {
make.title(@"Unable to View Response");
if (strongResponseData) {
make.message(@"No viewer content type: ").message(contentType);
} else {
make.message(@"The response has been purged from the cache");
}
make.button(@"OK").cancelStyle();
}];
};
} else {
BOOL emptyResponse = transaction.receivedDataLength == 0;
responseBodyRow.detailText = emptyResponse ? @"empty" : @"not in cache";
}

[rows addObject:responseBodyRow];

FLEXNetworkDetailRow *responseSizeRow = [FLEXNetworkDetailRow new];
Expand Down
Loading

0 comments on commit ac4c50b

Please sign in to comment.