2015-01-30 01:10:49 +00:00
|
|
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
|
|
|
|
|
|
|
#import "RCTAlertManager.h"
|
|
|
|
|
|
|
|
#import "RCTLog.h"
|
|
|
|
|
|
|
|
@interface RCTAlertManager() <UIAlertViewDelegate>
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation RCTAlertManager
|
|
|
|
{
|
|
|
|
NSMutableArray *_alerts;
|
|
|
|
NSMutableArray *_alertCallbacks;
|
|
|
|
NSMutableArray *_alertButtonKeys;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (instancetype)init
|
|
|
|
{
|
|
|
|
if ((self = [super init])) {
|
|
|
|
_alerts = [[NSMutableArray alloc] init];
|
|
|
|
_alertCallbacks = [[NSMutableArray alloc] init];
|
|
|
|
_alertButtonKeys = [[NSMutableArray alloc] init];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {NSDictionary} args Dictionary of the form
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
* @"message": @"<Alert message>",
|
|
|
|
* @"buttons": @[
|
|
|
|
* @{@"<key1>": @"<title1>"},
|
|
|
|
* @{@"<key2>": @"<cancelButtonTitle>"},
|
|
|
|
* ]
|
|
|
|
* }
|
|
|
|
* The key from the `buttons` dictionary is passed back in the callback on click.
|
|
|
|
* Buttons are displayed in the order they are specified. If "cancel" is used as
|
|
|
|
* the button key, it will be differently highlighted, according to iOS UI conventions.
|
|
|
|
*/
|
|
|
|
- (void)alertWithArgs:(NSDictionary *)args callback:(RCTResponseSenderBlock)callback
|
|
|
|
{
|
|
|
|
RCT_EXPORT();
|
|
|
|
|
|
|
|
NSString *title = args[@"title"];
|
|
|
|
NSString *message = args[@"message"];
|
|
|
|
NSArray *buttons = args[@"buttons"];
|
|
|
|
|
|
|
|
if (!title && !message) {
|
2015-03-02 19:36:55 +00:00
|
|
|
RCTLogError(@"Must specify either an alert title, or message, or both");
|
2015-01-30 01:10:49 +00:00
|
|
|
return;
|
|
|
|
} else if (buttons.count == 0) {
|
2015-03-02 19:36:55 +00:00
|
|
|
RCTLogError(@"Must have at least one button.");
|
2015-01-30 01:10:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
|
|
|
|
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
|
|
|
|
message:message
|
|
|
|
delegate:self
|
|
|
|
cancelButtonTitle:nil
|
|
|
|
otherButtonTitles:nil];
|
|
|
|
|
|
|
|
NSMutableArray *buttonKeys = [[NSMutableArray alloc] initWithCapacity:buttons.count];
|
|
|
|
|
|
|
|
NSInteger index = 0;
|
|
|
|
for (NSDictionary *button in buttons) {
|
|
|
|
if (button.count != 1) {
|
2015-03-02 19:36:55 +00:00
|
|
|
RCTLogError(@"Button definitions should have exactly one key.");
|
2015-01-30 01:10:49 +00:00
|
|
|
}
|
|
|
|
NSString *buttonKey = [button.allKeys firstObject];
|
|
|
|
NSString *buttonTitle = [button[buttonKey] description];
|
|
|
|
[alertView addButtonWithTitle:buttonTitle];
|
|
|
|
if ([buttonKey isEqualToString: @"cancel"]) {
|
|
|
|
alertView.cancelButtonIndex = index;
|
|
|
|
}
|
|
|
|
[buttonKeys addObject:buttonKey];
|
|
|
|
index ++;
|
|
|
|
}
|
|
|
|
|
|
|
|
[_alerts addObject:alertView];
|
|
|
|
[_alertCallbacks addObject:callback ?: ^(id unused) {}];
|
|
|
|
[_alertButtonKeys addObject:buttonKeys];
|
|
|
|
|
|
|
|
[alertView show];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark - UIAlertViewDelegate
|
|
|
|
|
|
|
|
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
|
|
|
{
|
|
|
|
NSUInteger index = [_alerts indexOfObject:alertView];
|
|
|
|
RCTAssert(index != NSNotFound, @"Dismissed alert was not recognised");
|
|
|
|
|
|
|
|
RCTResponseSenderBlock callback = _alertCallbacks[index];
|
|
|
|
NSArray *buttonKeys = _alertButtonKeys[index];
|
|
|
|
callback(@[buttonKeys[buttonIndex]]);
|
|
|
|
|
|
|
|
[_alerts removeObjectAtIndex:index];
|
|
|
|
[_alertCallbacks removeObjectAtIndex:index];
|
|
|
|
[_alertButtonKeys removeObjectAtIndex:index];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|