Skip to content

Commit dda1993

Browse files
committed
Using reflection to add the UNNotificationActionIcon
This is pretty ugly because we cannot use performSelector withObject. That method only allows up to 2 arguments so we must use NSInvocation.
1 parent d4859c1 commit dda1993

File tree

1 file changed

+37
-11
lines changed

1 file changed

+37
-11
lines changed

iOS_SDK/OneSignalSDK/Source/OneSignalHelper.m

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -567,20 +567,46 @@ + (UNNotificationRequest*)prepareUNNotificationRequest:(OSNotification*)notifica
567567
}
568568

569569
+ (UNNotificationAction *)createActionForButton:(NSDictionary *)button {
570+
NSString *buttonId = button[@"id"];
571+
NSString *buttonText = button[@"text"];
572+
570573
if (@available(iOS 15.0, *)) {
571-
UNNotificationActionIcon *icon;
572-
if (button[@"systemIcon"]) {
573-
icon = [UNNotificationActionIcon iconWithSystemImageName:button[@"systemIcon"]];
574-
} else if (button[@"templateIcon"]) {
575-
icon = [UNNotificationActionIcon iconWithTemplateImageName:button[@"templateIcon"]];
574+
// Using reflection for Xcode versions lower than 13
575+
id icon; // UNNotificationActionIcon
576+
let UNNotificationActionIconClass = NSClassFromString(@"UNNotificationActionIcon");
577+
if (UNNotificationActionIconClass) {
578+
if (button[@"systemIcon"]) {
579+
icon = [UNNotificationActionIconClass performSelector:@selector(iconWithSystemImageName:)
580+
withObject:button[@"systemIcon"]];
581+
} else if (button[@"templateIcon"]) {
582+
icon = [UNNotificationActionIconClass performSelector:@selector(iconWithTemplateImageName:)
583+
withObject:button[@"templateIcon"]];
584+
}
576585
}
577-
return [UNNotificationAction actionWithIdentifier:button[@"id"]
578-
title:button[@"text"]
579-
options:UNNotificationActionOptionForeground
580-
icon:icon];
586+
587+
// We need to use NSInvocation because performSelector only allows up to 2 arguments
588+
SEL actionSelector = NSSelectorFromString(@"actionWithIdentifier:title:options:icon:");
589+
UNNotificationAction * __unsafe_unretained action;
590+
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UNNotificationAction methodSignatureForSelector:actionSelector]];
591+
[invocation setTarget:[UNNotificationAction class]];
592+
[invocation setSelector:actionSelector];
593+
/*
594+
From Apple's Documentation on NSInvocation:
595+
Indices 0 and 1 indicate the hidden arguments self and _cmd, respectively;
596+
you should set these values directly with the target and selector properties.
597+
Use indices 2 and greater for the arguments normally passed in a message.
598+
*/
599+
NSUInteger actionOption = UNNotificationActionOptionForeground;
600+
[invocation setArgument:&buttonId atIndex:2];
601+
[invocation setArgument:&buttonText atIndex:3];
602+
[invocation setArgument:&actionOption atIndex:4];
603+
[invocation setArgument:&icon atIndex:5];
604+
[invocation invoke];
605+
[invocation getReturnValue:&action];
606+
return action;
581607
} else {
582-
return [UNNotificationAction actionWithIdentifier:button[@"id"]
583-
title:button[@"text"]
608+
return [UNNotificationAction actionWithIdentifier:buttonId
609+
title:buttonText
584610
options:UNNotificationActionOptionForeground];
585611
}
586612
}

0 commit comments

Comments
 (0)