Skip to content
This repository was archived by the owner on Jan 16, 2021. It is now read-only.

Commit b4a3219

Browse files
committed
Merge pull request #225 from ParsePlatform/nlutsenko.alerts
Use UIAlertController to present alerts if it's available.
2 parents 89650e4 + 4637462 commit b4a3219

File tree

7 files changed

+245
-108
lines changed

7 files changed

+245
-108
lines changed

ParseUI/Classes/Internal/Extensions/PFUIAlertView.h

+38-8
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,44 @@
2121

2222
#import <UIKit/UIKit.h>
2323

24-
@interface PFUIAlertView : UIAlertView
24+
NS_ASSUME_NONNULL_BEGIN
2525

26-
+ (void)showAlertViewWithTitle:(NSString *)title
27-
error:(NSError *)error;
28-
+ (void)showAlertViewWithTitle:(NSString *)title
29-
message:(NSString *)message;
30-
+ (void)showAlertViewWithTitle:(NSString *)title
31-
message:(NSString *)message
32-
cancelButtonTitle:(NSString *)cancelButtonTitle;
26+
typedef void(^PFUIAlertViewCompletion)(NSUInteger selectedOtherButtonIndex);
27+
typedef void(^PFUIAlertViewTextFieldCompletion)(UITextField *textField, NSUInteger selectedOtherButtonIndex);
28+
typedef void(^PFUIAlertViewTextFieldCustomizationHandler)(UITextField *textField);
29+
30+
@interface PFUIAlertView : NSObject
31+
32+
///--------------------------------------
33+
#pragma mark - Present
34+
///--------------------------------------
35+
36+
+ (void)presentAlertInViewController:(UIViewController *)viewController
37+
withTitle:(NSString *)title
38+
message:(nullable NSString *)message
39+
cancelButtonTitle:(NSString *)cancelButtonTitle
40+
otherButtonTitles:(nullable NSArray *)otherButtonTitles
41+
completion:(nullable PFUIAlertViewCompletion)completion;
42+
43+
+ (void)presentAlertInViewController:(UIViewController *)viewController
44+
withTitle:(NSString *)title
45+
message:(nullable NSString *)message
46+
textFieldCustomizationHandler:(PFUIAlertViewTextFieldCustomizationHandler)textFieldCustomizationHandler
47+
cancelButtonTitle:(NSString *)cancelButtonTitle
48+
otherButtonTitles:(nullable NSArray *)otherButtonTitles
49+
completion:(nullable PFUIAlertViewTextFieldCompletion)completion;
50+
51+
///--------------------------------------
52+
#pragma mark - Convenience
53+
///--------------------------------------
54+
55+
+ (void)presentAlertInViewController:(UIViewController *)viewController
56+
withTitle:(NSString *)title
57+
error:(NSError *)error;
58+
+ (void)presentAlertInViewController:(UIViewController *)viewController
59+
withTitle:(NSString *)title
60+
message:(nullable NSString *)message;
3361

3462
@end
63+
64+
NS_ASSUME_NONNULL_END

ParseUI/Classes/Internal/Extensions/PFUIAlertView.m

+174-17
Original file line numberDiff line numberDiff line change
@@ -23,34 +23,191 @@
2323

2424
#import "PFLocalization.h"
2525

26+
@interface PFUIAlertView () <UIAlertViewDelegate>
27+
28+
@property (nonatomic, copy) PFUIAlertViewCompletion completion;
29+
30+
@end
31+
2632
@implementation PFUIAlertView
2733

28-
+ (void)showAlertViewWithTitle:(NSString *)title error:(NSError *)error {
34+
///--------------------------------------
35+
#pragma mark - Present
36+
///--------------------------------------
37+
38+
+ (void)presentAlertInViewController:(UIViewController *)viewController
39+
withTitle:(NSString *)title
40+
message:(nullable NSString *)message
41+
cancelButtonTitle:(NSString *)cancelButtonTitle
42+
otherButtonTitles:(nullable NSArray *)otherButtonTitles
43+
completion:(nullable PFUIAlertViewCompletion)completion {
44+
if ([UIAlertController class] != nil) {
45+
__block UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
46+
message:message
47+
preferredStyle:UIAlertControllerStyleAlert];
48+
49+
void (^alertActionHandler)(UIAlertAction *) = [^(UIAlertAction *action) {
50+
if (completion) {
51+
// This block intentionally retains alertController, and releases it afterwards.
52+
if (action.style == UIAlertActionStyleCancel) {
53+
completion(NSNotFound);
54+
} else {
55+
NSUInteger index = [alertController.actions indexOfObject:action];
56+
completion(index - 1);
57+
}
58+
}
59+
alertController = nil;
60+
} copy];
61+
62+
[alertController addAction:[UIAlertAction actionWithTitle:cancelButtonTitle
63+
style:UIAlertActionStyleCancel
64+
handler:alertActionHandler]];
65+
66+
for (NSString *buttonTitle in otherButtonTitles) {
67+
[alertController addAction:[UIAlertAction actionWithTitle:buttonTitle
68+
style:UIAlertActionStyleDefault
69+
handler:alertActionHandler]];
70+
}
71+
72+
[viewController presentViewController:alertController animated:YES completion:nil];
73+
} else {
74+
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
75+
__block PFUIAlertView *pfAlertView = [[self alloc] init];
76+
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
77+
message:message
78+
delegate:nil
79+
cancelButtonTitle:cancelButtonTitle
80+
otherButtonTitles:nil];
81+
82+
for (NSString *buttonTitle in otherButtonTitles) {
83+
[alertView addButtonWithTitle:buttonTitle];
84+
}
85+
86+
pfAlertView.completion = ^(NSUInteger index) {
87+
if (completion) {
88+
completion(index);
89+
}
90+
91+
pfAlertView = nil;
92+
};
93+
94+
alertView.delegate = pfAlertView;
95+
[alertView show];
96+
#endif
97+
}
98+
}
99+
100+
+ (void)presentAlertInViewController:(UIViewController *)viewController
101+
withTitle:(NSString *)title
102+
message:(nullable NSString *)message
103+
textFieldCustomizationHandler:(PFUIAlertViewTextFieldCustomizationHandler)textFieldCustomizationHandler
104+
cancelButtonTitle:(NSString *)cancelButtonTitle
105+
otherButtonTitles:(nullable NSArray *)otherButtonTitles
106+
completion:(nullable PFUIAlertViewTextFieldCompletion)completion {
107+
if ([UIAlertController class] != nil) {
108+
__block UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
109+
message:message
110+
preferredStyle:UIAlertControllerStyleAlert];
111+
[alertController addTextFieldWithConfigurationHandler:textFieldCustomizationHandler];
112+
void (^alertActionHandler)(UIAlertAction *) = [^(UIAlertAction *action) {
113+
if (completion) {
114+
UITextField *textField = alertController.textFields.firstObject;
115+
// This block intentionally retains alertController, and releases it afterwards.
116+
if (action.style == UIAlertActionStyleCancel) {
117+
completion(textField, NSNotFound);
118+
} else {
119+
NSUInteger index = [alertController.actions indexOfObject:action];
120+
completion(textField, index - 1);
121+
}
122+
}
123+
alertController = nil;
124+
} copy];
125+
126+
[alertController addAction:[UIAlertAction actionWithTitle:cancelButtonTitle
127+
style:UIAlertActionStyleCancel
128+
handler:alertActionHandler]];
129+
130+
for (NSString *buttonTitle in otherButtonTitles) {
131+
[alertController addAction:[UIAlertAction actionWithTitle:buttonTitle
132+
style:UIAlertActionStyleDefault
133+
handler:alertActionHandler]];
134+
}
135+
136+
[viewController presentViewController:alertController animated:YES completion:nil];
137+
} else {
138+
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
139+
__block PFUIAlertView *pfAlertView = [[self alloc] init];
140+
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
141+
message:message
142+
delegate:nil
143+
cancelButtonTitle:cancelButtonTitle
144+
otherButtonTitles:nil];
145+
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
146+
for (NSString *buttonTitle in otherButtonTitles) {
147+
[alertView addButtonWithTitle:buttonTitle];
148+
}
149+
textFieldCustomizationHandler([alertView textFieldAtIndex:0]);
150+
151+
__weak UIAlertView *walertView = alertView;
152+
pfAlertView.completion = ^(NSUInteger index) {
153+
if (completion) {
154+
UITextField *textField = [walertView textFieldAtIndex:0];
155+
completion(textField, index);
156+
}
157+
158+
pfAlertView = nil;
159+
};
160+
161+
alertView.delegate = pfAlertView;
162+
[alertView show];
163+
#endif
164+
}
165+
}
166+
167+
///--------------------------------------
168+
#pragma mark - Convenience
169+
///--------------------------------------
170+
171+
+ (void)presentAlertInViewController:(UIViewController *)viewController
172+
withTitle:(NSString *)title
173+
error:(NSError *)error {
29174
NSString *message = error.userInfo[@"error"];
30175
if (!message) {
31-
message = [error.userInfo[@"originalError"] localizedDescription];
176+
message = [error.userInfo[@"originalError"] localizedDescription];
32177
}
33178
if (!message) {
34-
message = [error localizedDescription];
179+
message = [error localizedDescription];
35180
}
36-
[self showAlertViewWithTitle:title message:message];
181+
[self presentAlertInViewController:viewController withTitle:title message:message];
37182
}
38183

39-
+ (void)showAlertViewWithTitle:(NSString *)title message:(NSString *)message {
40-
[self showAlertViewWithTitle:title
41-
message:message
42-
cancelButtonTitle:PFLocalizedString(@"OK", @"OK")];
184+
+ (void)presentAlertInViewController:(UIViewController *)viewController
185+
withTitle:(NSString *)title
186+
message:(nullable NSString *)message {
187+
[self presentAlertInViewController:viewController
188+
withTitle:title
189+
message:message
190+
cancelButtonTitle:PFLocalizedString(@"OK", @"OK")
191+
otherButtonTitles:nil
192+
completion:nil];
43193
}
44194

45-
+ (void)showAlertViewWithTitle:(NSString *)title
46-
message:(NSString *)message
47-
cancelButtonTitle:(NSString *)cancelButtonTitle {
48-
UIAlertView *alertView = [[self alloc] initWithTitle:title
49-
message:message
50-
delegate:nil
51-
cancelButtonTitle:cancelButtonTitle
52-
otherButtonTitles:nil];
53-
[alertView show];
195+
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
196+
197+
///--------------------------------------
198+
#pragma mark - UIAlertViewDelegate
199+
///--------------------------------------
200+
201+
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
202+
if (self.completion) {
203+
if (buttonIndex == alertView.cancelButtonIndex) {
204+
self.completion(NSNotFound);
205+
} else {
206+
self.completion(buttonIndex - 1);
207+
}
208+
}
54209
}
55210

211+
#endif
212+
56213
@end

ParseUI/Classes/LogInViewController/PFLogInViewController.m

+19-29
Original file line numberDiff line numberDiff line change
@@ -235,17 +235,6 @@ - (BOOL)textFieldShouldReturn:(UITextField *)textField {
235235
return YES;
236236
}
237237

238-
///--------------------------------------
239-
#pragma mark - UIAlertViewDelegate
240-
///--------------------------------------
241-
242-
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
243-
if (buttonIndex != [alertView cancelButtonIndex]) {
244-
NSString *email = [alertView textFieldAtIndex:0].text;
245-
[self _requestPasswordResetWithEmail:email];
246-
}
247-
}
248-
249238
///--------------------------------------
250239
#pragma mark - Private
251240
///--------------------------------------
@@ -294,19 +283,22 @@ - (void)_forgotPasswordAction PF_EXTENSION_UNAVAILABLE("") {
294283
NSString *title = PFLocalizedString(@"Reset Password", @"Forgot password request title in PFLogInViewController");
295284
NSString *message = PFLocalizedString(@"Please enter the email address for your account.",
296285
@"Email request message in PFLogInViewController");
297-
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
298-
message:message
299-
delegate:self
300-
cancelButtonTitle:PFLocalizedString(@"Cancel", @"Cancel")
301-
otherButtonTitles:PFLocalizedString(@"OK", @"OK"), nil];
302-
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
303-
304-
UITextField *textField = [alertView textFieldAtIndex:0];
305-
textField.placeholder = PFLocalizedString(@"Email", @"Email");
306-
textField.keyboardType = UIKeyboardTypeEmailAddress;
307-
textField.returnKeyType = UIReturnKeyDone;
308-
309-
[alertView show];
286+
[PFUIAlertView presentAlertInViewController:self
287+
withTitle:title
288+
message:message
289+
textFieldCustomizationHandler:^(UITextField * _Nonnull textField) {
290+
textField.placeholder = PFLocalizedString(@"Email", @"Email");
291+
textField.keyboardType = UIKeyboardTypeEmailAddress;
292+
textField.returnKeyType = UIReturnKeyDone;
293+
}
294+
cancelButtonTitle:PFLocalizedString(@"Cancel", @"Cancel")
295+
otherButtonTitles:@[ PFLocalizedString(@"OK", @"OK")]
296+
completion:^(UITextField * _Nonnull textField, NSUInteger selectedOtherButtonIndex) {
297+
if (selectedOtherButtonIndex != NSNotFound) {
298+
NSString *email = textField.text;
299+
[self _requestPasswordResetWithEmail:email];
300+
}
301+
}];
310302
}
311303

312304
- (void)_requestPasswordResetWithEmail:(NSString *)email {
@@ -316,13 +308,11 @@ - (void)_requestPasswordResetWithEmail:(NSString *)email {
316308
@"Password reset success alert title in PFLogInViewController.");
317309
NSString *message = [NSString stringWithFormat:PFLocalizedString(@"An email with reset instructions has been sent to '%@'.",
318310
@"Password reset message in PFLogInViewController"), email];
319-
[PFUIAlertView showAlertViewWithTitle:title
320-
message:message
321-
cancelButtonTitle:PFLocalizedString(@"OK", @"OK")];
311+
[PFUIAlertView presentAlertInViewController:self withTitle:title message:message];
322312
} else {
323313
NSString *title = PFLocalizedString(@"Password Reset Failed",
324314
@"Password reset error alert title in PFLogInViewController.");
325-
[PFUIAlertView showAlertViewWithTitle:title error:error];
315+
[PFUIAlertView presentAlertInViewController:self withTitle:title error:error];
326316
}
327317
}];
328318
}
@@ -480,7 +470,7 @@ - (void)_loginDidFailWithError:(NSError *)error {
480470
} else {
481471
message = PFLocalizedString(@"Please try again", @"Generic login failed alert message in PFLogInViewController");
482472
}
483-
[PFUIAlertView showAlertViewWithTitle:title message:message];
473+
[PFUIAlertView presentAlertInViewController:self withTitle:title message:message];
484474
}
485475
[[NSNotificationCenter defaultCenter] postNotificationName:PFLogInFailureNotification object:self];
486476
}

ParseUI/Classes/ProductTableViewController/PFProductTableViewController.m

+4-4
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,15 @@ - (void)objectsDidLoad:(NSError *)error {
8888

8989
cell.state = PFPurchaseTableViewCellStateDownloading;
9090
[PFPurchase downloadAssetForTransaction:transaction
91-
completion:^(NSString *filePath, NSError *downloadError) {
92-
if (!downloadError) {
91+
completion:^(NSString *filePath, NSError *error) {
92+
if (!error) {
9393
cell.state = PFPurchaseTableViewCellStateDownloaded;
9494
} else {
9595
cell.state = PFPurchaseTableViewCellStateNormal;
9696

9797
NSString *title = PFLocalizedString(@"Download Error",
9898
@"Download Error");
99-
[PFUIAlertView showAlertViewWithTitle:title error:downloadError];
99+
[PFUIAlertView presentAlertInViewController:self withTitle:title error:error];
100100
}
101101
}
102102
progress:^(int percentDone) {
@@ -175,7 +175,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
175175
[PFPurchase buyProduct:product.productIdentifier block:^(NSError *error) {
176176
if (error) {
177177
NSString *title = PFLocalizedString(@"Purchase Error", @"Purchase Error");
178-
[PFUIAlertView showAlertViewWithTitle:title error:error];
178+
[PFUIAlertView presentAlertInViewController:self withTitle:title error:error];
179179
}
180180
}];
181181
}

0 commit comments

Comments
 (0)