Skip to content

Commit 1f23455

Browse files
emawbyjkasten2
authored andcommitted
Using alertcontrollers instead of alertviews via the OneSignalDialogController
Keeping OneSignalAlertViewDelegate for iOS 7. This will be removed in the next major release. Updating OneSignalDialogControllerOverrider and in app alert unit tests to use the dialog controller.
1 parent 04c5dbe commit 1f23455

15 files changed

+193
-64
lines changed

iOS_SDK/OneSignalSDK/Source/OSMessagingController.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN
3939

4040
@end
4141

42-
@interface OSMessagingController : NSObject <OSInAppMessageViewControllerDelegate, OSTriggerControllerDelegate, OSMessagingControllerDelegate, UIAlertViewDelegate>
42+
@interface OSMessagingController : NSObject <OSInAppMessageViewControllerDelegate, OSTriggerControllerDelegate, OSMessagingControllerDelegate>
4343

4444
@property (class, readonly) BOOL isInAppMessagingPaused;
4545

iOS_SDK/OneSignalSDK/Source/OSMessagingController.m

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#import "OSInAppMessageController.h"
3636
#import "OSInAppMessagePrompt.h"
3737
#import "OneSignalCommonDefines.h"
38+
#import "OneSignalDialogController.h"
3839

3940
@interface OneSignal ()
4041

@@ -547,18 +548,14 @@ - (void)showAlertDialogMessage:(OSInAppMessage *)inAppMessage
547548
promptActions:(NSArray<NSObject<OSInAppMessagePrompt> *> *)promptActions {
548549
_currentInAppMessage = inAppMessage;
549550
_currentPromptActions = promptActions;
550-
let messageTitle = @"Location Not Available";
551-
let message = @"Looks like this app doesn't have location services configured. Please see OneSignal docs for more information.";
552-
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:messageTitle
553-
message:message
554-
delegate:self
555-
cancelButtonTitle:nil
556-
otherButtonTitles:@"OK", nil];
557-
[alert show];
558-
}
559-
560-
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
561-
[self handlePromptActions:_currentPromptActions withMessage:_currentInAppMessage];
551+
552+
let message = NSLocalizedString(@"Looks like this app doesn't have location services configured. Please see OneSignal docs for more information.", @"An alert message indicating that the application is not configured to use have location services.");
553+
let title = NSLocalizedString(@"Location Not Available", @"An alert title indicating that the location service is unavailable.");
554+
let okAction = NSLocalizedString(@"OK", @"Allows the user to acknowledge and dismiss the alert");
555+
[[OneSignalDialogController sharedInstance] presentDialogWithTitle:title withMessage:message withActions:nil cancelTitle:okAction withActionCompletion:^(int tappedActionIndex) {
556+
//completion is called on the main thread
557+
[self handlePromptActions:_currentPromptActions withMessage:_currentInAppMessage];
558+
}];
562559
}
563560

564561
- (void)messageViewDidSelectAction:(OSInAppMessage *)message withAction:(OSInAppMessageAction *)action {

iOS_SDK/OneSignalSDK/Source/OneSignal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ typedef NS_ENUM(NSUInteger, OSNotificationDisplayType) {
5959
/*Notification is silent, or app is in focus but InAppAlertNotifications are disabled*/
6060
OSNotificationDisplayTypeNone,
6161

62-
/*Default UIAlertView display*/
62+
/*Default UIAlertController display*/
6363
OSNotificationDisplayTypeInAppAlert,
6464

6565
/*iOS native notification display*/

iOS_SDK/OneSignalSDK/Source/OneSignal.m

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#import "OneSignalReachability.h"
3434
#import "OneSignalJailbreakDetection.h"
3535
#import "OneSignalMobileProvision.h"
36-
#import "OneSignalAlertViewDelegate.h"
3736
#import "OneSignalHelper.h"
3837
#import "UNUserNotificationCenter+OneSignal.h"
3938
#import "OneSignalSelectorHelpers.h"
@@ -893,7 +892,7 @@ void onesignal_Log(ONE_S_LOG_LEVEL logLevel, NSString* message) {
893892
NSLog(@"%@", [levelString stringByAppendingString:message]);
894893

895894
if (logLevel <= _visualLogLevel) {
896-
[[OneSignalDialogController sharedInstance] presentDialogWithTitle:levelString withMessage:message withAction:nil cancelTitle:NSLocalizedString(@"Close", @"Close button") withActionCompletion:nil];
895+
[[OneSignalDialogController sharedInstance] presentDialogWithTitle:levelString withMessage:message withActions:nil cancelTitle:NSLocalizedString(@"Close", @"Close button") withActionCompletion:nil];
897896
}
898897
}
899898

@@ -974,10 +973,10 @@ + (void)promptForPushNotificationsWithUserResponse:(void (^)(BOOL accepted))comp
974973
localizedMessage = NSLocalizedString(@"You currently have notifications turned off for this application. You can open Settings to re-enable them", @"A message explaining that users can open Settings to re-enable push notifications");
975974

976975

977-
[[OneSignalDialogController sharedInstance] presentDialogWithTitle:localizedTitle withMessage:localizedMessage withAction:localizedSettingsActionTitle cancelTitle:localizedCancelActionTitle withActionCompletion:^(BOOL tappedAction) {
976+
[[OneSignalDialogController sharedInstance] presentDialogWithTitle:localizedTitle withMessage:localizedMessage withActions:@[localizedSettingsActionTitle] cancelTitle:localizedCancelActionTitle withActionCompletion:^(int tappedActionIndex) {
978977

979978
//completion is called on the main thread
980-
if (tappedAction)
979+
if (tappedActionIndex > -1)
981980
[self presentAppSettings];
982981
}];
983982

@@ -1977,7 +1976,7 @@ + (void)notificationReceived:(NSDictionary*)messageDict foreground:(BOOL)foregro
19771976
let inAppAlert = (self.inFocusDisplayType == OSNotificationDisplayTypeInAppAlert);
19781977
// Make sure it is not a silent one do display, if inAppAlerts are enabled
19791978
if (inAppAlert && !isPreview && ![OneSignalHelper isRemoteSilentNotification:messageDict]) {
1980-
[OneSignalAlertView showInAppAlert:messageDict];
1979+
[[OneSignalDialogController sharedInstance] presentDialogWithMessageDict:messageDict];
19811980
return;
19821981
}
19831982

iOS_SDK/OneSignalSDK/Source/OneSignalAlertViewDelegate.m

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,14 @@ + (void)showInAppAlert:(NSDictionary*)messageDict {
7373

7474
@end
7575

76-
7776
@implementation OneSignalAlertViewDelegate
7877

7978
NSDictionary* mMessageDict;
8079

81-
/*
82-
delegateReference exist to keep ARC from cleaning up this object when it goes out of scope.
83-
This is becuase UIAlertView delegate is set to weak instead of strong
84-
*/
80+
81+
//delegateReference exist to keep ARC from cleaning up this object when it goes out of scope.
82+
//This is becuase UIAlertView delegate is set to weak instead of strong
83+
8584
static NSMutableArray* delegateReference;
8685

8786
- (id)initWithMessageDict:(NSDictionary*)messageDict {
@@ -138,3 +137,4 @@ - (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)button
138137
}
139138

140139
@end
140+

iOS_SDK/OneSignalSDK/Source/OneSignalDialogController.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@
2929
#import <UIKit/UIKit.h>
3030

3131
NS_ASSUME_NONNULL_BEGIN
32-
typedef void (^OSDialogActionCompletion)(BOOL tappedAction);
32+
typedef void (^OSDialogActionCompletion)(int tappedActionIndex);
3333

3434
@interface OneSignalDialogController : NSObject <UIAlertViewDelegate>
3535
+ (instancetype _Nonnull)sharedInstance;
36-
- (void)presentDialogWithTitle:(NSString * _Nonnull)title withMessage:(NSString * _Nonnull)message withAction:(NSString * _Nullable)actionTitle cancelTitle:(NSString * _Nonnull)cancelTitle withActionCompletion:(OSDialogActionCompletion _Nullable)completion;
36+
- (void)presentDialogWithTitle:(NSString * _Nonnull)title withMessage:(NSString * _Nonnull)message withActions:(NSArray<NSString *> * _Nullable)actionTitles cancelTitle:(NSString * _Nonnull)cancelTitle withActionCompletion:(OSDialogActionCompletion _Nullable)completion;
37+
38+
- (void)presentDialogWithMessageDict:(NSDictionary *)messageDict;
39+
40+
- (void)clearQueue;
3741
@end
3842

3943
NS_ASSUME_NONNULL_END

iOS_SDK/OneSignalSDK/Source/OneSignalDialogController.m

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#import "OneSignalDialogController.h"
2929
#import "OneSignalHelper.h"
3030
#import "OneSignalDialogRequest.h"
31+
#import "OneSignalAlertViewDelegate.h"
3132

3233
/*
3334
This class handles displaying all dialogs (alerts) for the SDK
@@ -41,6 +42,16 @@ @interface OneSignalDialogController ()
4142

4243
@end
4344

45+
@interface OneSignal ()
46+
47+
+ (void)handleNotificationOpened:(NSDictionary*)messageDict
48+
foreground:(BOOL)foreground
49+
isActive:(BOOL)isActive
50+
actionType:(OSNotificationActionType)actionType
51+
displayType:(OSNotificationDisplayType)displayType;
52+
53+
@end
54+
4455
@implementation OneSignalDialogController
4556

4657
+ (instancetype _Nonnull)sharedInstance {
@@ -55,11 +66,75 @@ + (instancetype _Nonnull)sharedInstance {
5566
return sharedInstance;
5667
}
5768

58-
- (void)presentDialogWithTitle:(NSString * _Nonnull)title withMessage:(NSString * _Nonnull)message withAction:(NSString * _Nullable)actionTitle cancelTitle:(NSString * _Nonnull)cancelTitle withActionCompletion:(OSDialogActionCompletion _Nullable)completion {
69+
- (NSArray<NSString *> *)getActionTitlesFromPayload:(OSNotificationPayload *)payload {
70+
NSMutableArray<NSString *> *actionTitles = [NSMutableArray<NSString *> new];
71+
if (payload.actionButtons) {
72+
for (id button in payload.actionButtons) {
73+
[actionTitles addObject:button[@"text"]];
74+
}
75+
}
76+
return actionTitles;
77+
}
78+
79+
- (void)presentDialogWithMessageDict:(NSDictionary *)messageDict {
80+
if ([OneSignalHelper isIOSVersionLessThan:@"8.0"]) {
81+
[OneSignalAlertView showInAppAlert:messageDict];
82+
}
83+
let payload = [OSNotificationPayload parseWithApns:messageDict];
84+
// Add action buttons to payload
85+
NSArray<NSString *> *actionTitles = [self getActionTitlesFromPayload:payload];
86+
87+
[self presentDialogWithTitle:payload.title withMessage:payload.body withActions:actionTitles cancelTitle:@"Close" withActionCompletion:^(int tappedActionIndex) {
88+
OSNotificationActionType actionType = OSNotificationActionTypeOpened;
89+
90+
NSDictionary *finalDict = messageDict;
91+
92+
if (tappedActionIndex > -1) {
93+
94+
actionType = OSNotificationActionTypeActionTaken;
95+
96+
NSMutableDictionary* userInfo = [messageDict mutableCopy];
97+
98+
// Fixed for iOS 7, which has 'actionbuttons' as a root property of the dict, not in 'os_data'
99+
if (messageDict[@"os_data"] && !messageDict[@"actionbuttons"]) {
100+
if ([messageDict[@"os_data"][@"buttons"] isKindOfClass:[NSDictionary class]])
101+
userInfo[@"actionSelected"] = messageDict[@"os_data"][@"buttons"][@"o"][tappedActionIndex - 1][@"i"];
102+
else
103+
userInfo[@"actionSelected"] = messageDict[@"os_data"][@"buttons"][tappedActionIndex][@"i"];
104+
} else if (messageDict[@"buttons"]) {
105+
userInfo[@"actionSelected"] = messageDict[@"buttons"][tappedActionIndex][@"i"];
106+
} else {
107+
NSMutableDictionary* customDict = userInfo[@"custom"] ? [userInfo[@"custom"] mutableCopy] : [NSMutableDictionary new];
108+
NSMutableDictionary* additionalData = customDict[@"a"] ? [[NSMutableDictionary alloc] initWithDictionary:customDict[@"a"]] : [NSMutableDictionary new];
109+
110+
if([additionalData[@"actionButtons"] isKindOfClass:[NSArray class]]) {
111+
additionalData[@"actionSelected"] = additionalData[@"actionButtons"][tappedActionIndex - 1][@"id"];
112+
} else if([messageDict[@"o"] isKindOfClass:[NSArray class]]) {
113+
additionalData[@"actionSelected"] = messageDict[@"o"][tappedActionIndex][@"i"];
114+
} else if ([messageDict[@"actionbuttons"] isKindOfClass:[NSArray class]]) {
115+
additionalData[@"actionSelected"] = messageDict[@"actionbuttons"][tappedActionIndex][@"i"];
116+
}
117+
118+
customDict[@"a"] = additionalData;
119+
userInfo[@"custom"] = customDict;
120+
}
121+
122+
finalDict = userInfo;
123+
}
124+
125+
[OneSignal handleNotificationOpened:finalDict foreground:YES isActive:YES actionType:actionType displayType:OSNotificationDisplayTypeInAppAlert];
126+
}];
127+
128+
// Message received that was displayed (Foreground + InAppAlert is true)
129+
// Call received callback
130+
[OneSignalHelper handleNotificationReceived:OSNotificationDisplayTypeInAppAlert fromBackground:NO];
131+
}
132+
133+
- (void)presentDialogWithTitle:(NSString * _Nonnull)title withMessage:(NSString * _Nonnull)message withActions:(NSArray<NSString *> * _Nullable)actionTitles cancelTitle:(NSString * _Nonnull)cancelTitle withActionCompletion:(OSDialogActionCompletion _Nullable)completion {
59134

60135
//ensure this UI code executes on the main thread
61136
dispatch_async(dispatch_get_main_queue(), ^{
62-
let request = [[OSDialogRequest alloc] initWithTitle:title withMessage:message withActionTitle:actionTitle withCancelTitle:cancelTitle withCompletion:completion];
137+
let request = [[OSDialogRequest alloc] initWithTitle:title withMessage:message withActionTitles:actionTitles withCancelTitle:cancelTitle withCompletion:completion];
63138

64139
[self.queue addObject:request];
65140

@@ -75,8 +150,12 @@ - (void)presentDialogWithTitle:(NSString * _Nonnull)title withMessage:(NSString
75150
- (void)displayDialog:(OSDialogRequest * _Nonnull)request {
76151
//iOS 7
77152
if ([OneSignalHelper isIOSVersionLessThan:@"8.0"]) {
78-
79-
let alertView = [[UIAlertView alloc] initWithTitle:request.title message:request.message delegate:self cancelButtonTitle:request.cancelTitle otherButtonTitles:request.actionTitle, nil];
153+
let alertView = [[UIAlertView alloc] initWithTitle:request.title message:request.message delegate:self cancelButtonTitle:request.cancelTitle otherButtonTitles:nil, nil];
154+
if (request.actionTitles != nil) {
155+
for (NSString *actionTitle in request.actionTitles) {
156+
[alertView addButtonWithTitle:actionTitle];
157+
}
158+
}
80159

81160
[alertView show];
82161

@@ -89,19 +168,26 @@ - (void)displayDialog:(OSDialogRequest * _Nonnull)request {
89168
let controller = [UIAlertController alertControllerWithTitle:request.title message:request.message preferredStyle:UIAlertControllerStyleAlert];
90169

91170
[controller addAction:[UIAlertAction actionWithTitle:request.cancelTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
92-
[self delayResult:false];
171+
[self delayResult:-1];
93172
}]];
94173

95-
if (request.actionTitle != nil) {
96-
[controller addAction:[UIAlertAction actionWithTitle:request.actionTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
97-
[self delayResult:true];
98-
}]];
174+
if (request.actionTitles != nil) {
175+
for (int i = 0; i < request.actionTitles.count; i++) {
176+
NSString *actionTitle = request.actionTitles[i];
177+
[controller addAction:[UIAlertAction actionWithTitle:actionTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
178+
[self delayResult:i];
179+
}]];
180+
}
99181
}
100182

101183
[rootViewController presentViewController:controller animated:true completion:nil];
102184
}
103185

104-
- (void)delayResult:(BOOL)result {
186+
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
187+
[self delayResult:(int)buttonIndex-1];
188+
}
189+
190+
- (void)delayResult:(int)result {
105191
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
106192
let currentDialog = self.queue.firstObject;
107193

@@ -120,8 +206,8 @@ - (void)delayResult:(BOOL)result {
120206
});
121207
}
122208

123-
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
124-
[self delayResult:buttonIndex > 0];
209+
- (void)clearQueue {
210+
self.queue = [NSMutableArray new];
125211
}
126212

127213
@end

iOS_SDK/OneSignalSDK/Source/OneSignalDialogRequest.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ NS_ASSUME_NONNULL_BEGIN
3434

3535
@property (strong, nonatomic, nonnull) NSString *title;
3636
@property (strong, nonatomic, nonnull) NSString *message;
37-
@property (strong, nonatomic, nullable) NSString *actionTitle;
37+
@property (strong, nonatomic, nullable) NSArray<NSString *> *actionTitles;
3838
@property (strong, nonatomic, nonnull) NSString *cancelTitle;
3939
@property (nonatomic, nullable) OSDialogActionCompletion completion;
4040

4141
- (instancetype _Nonnull)initWithTitle:(NSString * _Nonnull)title withMessage:(NSString * _Nonnull)message withActionTitle:(NSString * _Nullable)actionTitle withCancelTitle:(NSString * _Nonnull)cancelTitle withCompletion:(OSDialogActionCompletion _Nullable)completion;
4242

43+
- (instancetype _Nonnull)initWithTitle:(NSString * _Nonnull)title withMessage:(NSString * _Nonnull)message withActionTitles:(NSArray<NSString *> * _Nullable)actionTitles withCancelTitle:(NSString * _Nonnull)cancelTitle withCompletion:(OSDialogActionCompletion _Nullable)completion;
44+
4345
@end
4446

4547
NS_ASSUME_NONNULL_END

iOS_SDK/OneSignalSDK/Source/OneSignalDialogRequest.m

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,26 @@
2929

3030
@implementation OSDialogRequest
3131

32-
- (instancetype _Nonnull)initWithTitle:(NSString * _Nonnull)title withMessage:(NSString * _Nonnull)message withActionTitle:(NSString * _Nullable)actionTitle withCancelTitle:(NSString * _Nonnull)cancelTitle withCompletion:(OSDialogActionCompletion _Nullable)completion
33-
{
32+
- (instancetype _Nonnull)initWithTitle:(NSString * _Nonnull)title withMessage:(NSString * _Nonnull)message withActionTitle:(NSString * _Nullable)actionTitle withCancelTitle:(NSString * _Nonnull)cancelTitle withCompletion:(OSDialogActionCompletion _Nullable)completion {
33+
3434
self = [super init];
3535
if (self) {
3636
self.title = title;
3737
self.message = message;
38-
self.actionTitle = actionTitle;
38+
self.actionTitles = @[actionTitle];
39+
self.cancelTitle = cancelTitle;
40+
self.completion = completion;
41+
}
42+
return self;
43+
}
44+
45+
- (instancetype _Nonnull)initWithTitle:(NSString * _Nonnull)title withMessage:(NSString * _Nonnull)message withActionTitles:(NSArray<NSString *> * _Nullable)actionTitles withCancelTitle:(NSString * _Nonnull)cancelTitle withCompletion:(OSDialogActionCompletion _Nullable)completion {
46+
47+
self = [super init];
48+
if (self) {
49+
self.title = title;
50+
self.message = message;
51+
self.actionTitles = actionTitles;
3952
self.cancelTitle = cancelTitle;
4053
self.completion = completion;
4154
}

iOS_SDK/OneSignalSDK/Source/OneSignalHelper.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -943,8 +943,8 @@ + (void) displayWebView:(NSURL*)url {
943943
let openAction = NSLocalizedString(@"Open", @"Allows the user to open the URL/website");
944944
let cancelAction = NSLocalizedString(@"Cancel", @"The user won't open the URL/website");
945945

946-
[[OneSignalDialogController sharedInstance] presentDialogWithTitle:title withMessage:message withAction:openAction cancelTitle:cancelAction withActionCompletion:^(BOOL tappedAction) {
947-
openUrlBlock(tappedAction);
946+
[[OneSignalDialogController sharedInstance] presentDialogWithTitle:title withMessage:message withActions:@[openAction] cancelTitle:cancelAction withActionCompletion:^(int tappedActionIndex) {
947+
openUrlBlock(tappedActionIndex > -1);
948948
}];
949949
} else {
950950
openUrlBlock(true);

0 commit comments

Comments
 (0)