diff --git a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSDeviceUtils.h b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSDeviceUtils.h index e646d6d1d..6cee7a212 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSDeviceUtils.h +++ b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSDeviceUtils.h @@ -31,9 +31,6 @@ @interface OSDeviceUtils : NSObject -+ (NSString *)getCurrentDeviceVersion; -+ (BOOL)isIOSVersionGreaterThanOrEqual:(NSString *)version; -+ (BOOL)isIOSVersionLessThan:(NSString *)version; + (NSString*)getDeviceVariant; @end diff --git a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSDeviceUtils.m b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSDeviceUtils.m index f5343df66..f7ac224d9 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSDeviceUtils.m +++ b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSDeviceUtils.m @@ -32,18 +32,6 @@ of this software and associated documentation files (the "Software"), to deal @implementation OSDeviceUtils -+ (NSString *)getCurrentDeviceVersion { - return [[UIDevice currentDevice] systemVersion]; -} - -+ (BOOL)isIOSVersionGreaterThanOrEqual:(NSString *)version { - return [[self getCurrentDeviceVersion] compare:version options:NSNumericSearch] != NSOrderedAscending; -} - -+ (BOOL)isIOSVersionLessThan:(NSString *)version { - return [[self getCurrentDeviceVersion] compare:version options:NSNumericSearch] == NSOrderedAscending; -} - + (NSString*)getSystemInfoMachine { // e.g. @"x86_64" or @"iPhone9,3" struct utsname systemInfo; diff --git a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.m b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.m index 4c00a980b..175c2995d 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.m +++ b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.m @@ -141,9 +141,7 @@ - (void)parseAlertField:(NSObject*)alert { _body = (NSString*)alert; } -// Only used on iOS 9 and older. -// - Or if the OneSignal server hasn't received the iOS version update. -// May also be used if OneSignal server hasn't received the SDK version 2.4.0+ update event +// Parses minified payloads that can still arrive before the server receives current SDK and device metadata. - (void)parseRemoteSlient:(NSDictionary*)payload { [self parseAlertField:payload[@"m"]]; _badge = [payload[@"b"] intValue]; diff --git a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OneSignalCommonDefines.h b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OneSignalCommonDefines.h index bab5397e1..9ac8c3011 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OneSignalCommonDefines.h +++ b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OneSignalCommonDefines.h @@ -56,7 +56,6 @@ #define OSUD_PERMISSION_ACCEPTED_FROM @"ONESIGNAL_PERMISSION_ACCEPTED_LAST" // * OSUD_PERMISSION_ACCEPTED_FROM #define OSUD_WAS_PROMPTED_FOR_NOTIFICATIONS_TO @"OSUD_WAS_PROMPTED_FOR_NOTIFICATIONS_TO" // OSUD_WAS_PROMPTED_FOR_NOTIFICATIONS_TO #define OSUD_WAS_PROMPTED_FOR_NOTIFICATIONS_FROM @"OS_HAS_PROMPTED_FOR_NOTIFICATIONS_LAST" // * OSUD_WAS_PROMPTED_FOR_NOTIFICATIONS_FROM -#define OSUD_WAS_NOTIFICATION_PROMPT_ANSWERED_TO @"OS_NOTIFICATION_PROMPT_ANSWERED" // * OSUD_WAS_NOTIFICATION_PROMPT_ANSWERED_TO #define OSUD_WAS_NOTIFICATION_PROMPT_ANSWERED_FROM @"OS_NOTIFICATION_PROMPT_ANSWERED_LAST" // * OSUD_WAS_NOTIFICATION_PROMPT_ANSWERED_FROM #define OSUD_PROVISIONAL_PUSH_AUTHORIZATION_TO @"OSUD_PROVISIONAL_PUSH_AUTHORIZATION_TO" // OSUD_PROVISIONAL_PUSH_AUTHORIZATION_TO #define OSUD_PROVISIONAL_PUSH_AUTHORIZATION_FROM @"ONESIGNAL_PROVISIONAL_AUTHORIZATION_LAST" // * OSUD_PROVISIONAL_PUSH_AUTHORIZATION_FROM @@ -113,11 +112,6 @@ #define OSUD_UNSENT_ACTIVE_TIME @"GT_UNSENT_ACTIVE_TIME" // * OSUD_UNSENT_ACTIVE_TIME #define OSUD_UNSENT_ACTIVE_TIME_ATTRIBUTED @"GT_UNSENT_ACTIVE_TIME_ATTRIBUTED" // * OSUD_UNSENT_ACTIVE_TIME_ATTRIBUTED -// Deprecated Selectors -#define DEPRECATED_SELECTORS @[ @"application:didReceiveLocalNotification:", \ - @"application:handleActionWithIdentifier:forLocalNotification:completionHandler:", \ - @"application:handleActionWithIdentifier:forLocalNotification:withResponseInfo:completionHandler:" ] - // To avoid undefined symbol compiler errors on older versions of Xcode, // instead of using UNAuthorizationOptionProvisional directly, we will use // it indirectly with these macros diff --git a/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtension.h b/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtension.h index 9a0853efc..4deaeda8d 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtension.h +++ b/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtension.h @@ -35,10 +35,8 @@ @interface OneSignalExtension : NSObject #pragma mark NotificationService Extension #pragma clang diagnostic ignored "-Wnullability-completeness" -// iOS 10 only -// Process from Notification Service Extension. -// Used for iOS Media Attachemtns and Action Buttons. -+ (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest* _Nonnull)request withMutableNotificationContent:(UNMutableNotificationContent* _Nullable)replacementContent __deprecated_msg("Please use didReceiveNotificationExtensionRequest:withMutableNotificationContent:withContentHandler: instead."); +// Call from a UNNotificationServiceExtension on iOS 10 and later. +// Processes media attachments and action buttons. + (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest* _Nonnull)request withMutableNotificationContent:(UNMutableNotificationContent* _Nullable)replacementContent withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler; + (UNMutableNotificationContent*)serviceExtensionTimeWillExpireRequest:(UNNotificationRequest* _Nonnull)request withMutableNotificationContent:(UNMutableNotificationContent* _Nullable)replacementContent; @end diff --git a/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtension.m b/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtension.m index a0cb3f64b..b60b15475 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtension.m +++ b/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtension.m @@ -30,13 +30,6 @@ of this software and associated documentation files (the "Software"), to deal @implementation OneSignalExtension -// Called from the app's Notification Service Extension -+ (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest*)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent { - return [OneSignalNotificationServiceExtensionHandler - didReceiveNotificationExtensionRequest:request - withMutableNotificationContent:replacementContent]; -} - // Called from the app's Notification Service Extension. Calls contentHandler() to display the notification + (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest*)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { diff --git a/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Controller/OSMessagingController.m b/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Controller/OSMessagingController.m index 067787d89..5e1256482 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Controller/OSMessagingController.m +++ b/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Controller/OSMessagingController.m @@ -165,7 +165,6 @@ @implementation OSMessagingController static dispatch_once_t once; + (OSMessagingController *)sharedInstance { dispatch_once(&once, ^{ - // Make sure only devices with iOS 10 or newer can use IAMs if ([self doesDeviceSupportIAM]) { sharedInstance = [OSMessagingController new]; } else { @@ -209,9 +208,8 @@ + (BOOL)doesDeviceSupportIAM { // We could support in the future after we reslove the display issues. if ([@"Mac" isEqualToString:[OSDeviceUtils getDeviceVariant]]) return false; - - // Only support iOS 10 and newer due to Safari 9 WebView issues - return [OSDeviceUtils isIOSVersionGreaterThanOrEqual:@"10.0"]; + + return true; } - (instancetype)init { diff --git a/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/UI/OSInAppMessageView.m b/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/UI/OSInAppMessageView.m index e74d98d5d..aef2b358b 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/UI/OSInAppMessageView.m +++ b/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/UI/OSInAppMessageView.m @@ -171,25 +171,23 @@ - (void)resetWebViewToMaxBoundsAndResizeHeight:(void (^) (NSNumber *newHeight)) } - (void)updateSafeAreaInsets { - if (@available(iOS 11, *)) { - UIWindow *keyWindow = UIApplication.sharedApplication.keyWindow; - CGFloat top = keyWindow.safeAreaInsets.top; - CGFloat bottom = keyWindow.safeAreaInsets.bottom; - CGFloat right = keyWindow.safeAreaInsets.right; - CGFloat left = keyWindow.safeAreaInsets.left; - NSString *safeAreaInsetsObjectString = [NSString stringWithFormat:OS_JS_SAFE_AREA_INSETS_OBJ,top, bottom, right, left]; - - NSString *setInsetsString = [NSString stringWithFormat:OS_SET_SAFE_AREA_INSETS_METHOD, safeAreaInsetsObjectString]; - [self.webView evaluateJavaScript:setInsetsString completionHandler:^(NSDictionary *result, NSError * _Nullable error) { - if (error) { - NSString *errorMessage = [NSString stringWithFormat:@"Javascript Method: %@ Evaluated with Error: %@", OS_SET_SAFE_AREA_INSETS_METHOD, error]; - [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:errorMessage]; - return; - } - NSString *successMessage = [NSString stringWithFormat:@"Javascript Method: %@ Evaluated with Success: %@", OS_SET_SAFE_AREA_INSETS_METHOD, result]; - [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:successMessage]; - }]; - } + UIWindow *keyWindow = UIApplication.sharedApplication.keyWindow; + CGFloat top = keyWindow.safeAreaInsets.top; + CGFloat bottom = keyWindow.safeAreaInsets.bottom; + CGFloat right = keyWindow.safeAreaInsets.right; + CGFloat left = keyWindow.safeAreaInsets.left; + NSString *safeAreaInsetsObjectString = [NSString stringWithFormat:OS_JS_SAFE_AREA_INSETS_OBJ,top, bottom, right, left]; + + NSString *setInsetsString = [NSString stringWithFormat:OS_SET_SAFE_AREA_INSETS_METHOD, safeAreaInsetsObjectString]; + [self.webView evaluateJavaScript:setInsetsString completionHandler:^(NSDictionary *result, NSError * _Nullable error) { + if (error) { + NSString *errorMessage = [NSString stringWithFormat:@"Javascript Method: %@ Evaluated with Error: %@", OS_SET_SAFE_AREA_INSETS_METHOD, error]; + [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:errorMessage]; + return; + } + NSString *successMessage = [NSString stringWithFormat:@"Javascript Method: %@ Evaluated with Success: %@", OS_SET_SAFE_AREA_INSETS_METHOD, result]; + [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:successMessage]; + }]; } - (NSNumber *)extractHeightFromMetaDataPayload:(NSDictionary *)result { @@ -210,8 +208,7 @@ - (void)setupWebViewConstraints { self.webView.layer.cornerRadius = 10.0f; self.webView.layer.masksToBounds = true; - if (@available(iOS 11, *)) - self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; [self.webView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor].active = true; [self.webView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor].active = true; diff --git a/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/UI/OSInAppMessageViewController.m b/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/UI/OSInAppMessageViewController.m index bdefdb3f6..873e7447d 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/UI/OSInAppMessageViewController.m +++ b/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/UI/OSInAppMessageViewController.m @@ -293,22 +293,20 @@ - (void)parseContentData:(NSDictionary *)data { - (NSString *)setContentInsetsInHTML:(NSString *)html { NSMutableString *newHTML = [[NSMutableString alloc] initWithString:html]; - if (@available(iOS 11, *)) { - UIWindow *keyWindow = UIApplication.sharedApplication.keyWindow; - if (!keyWindow) { - return newHTML; - } - CGFloat top = keyWindow.safeAreaInsets.top; - CGFloat bottom = keyWindow.safeAreaInsets.bottom; - CGFloat right = keyWindow.safeAreaInsets.right; - CGFloat left = keyWindow.safeAreaInsets.left; - NSString *safeAreaInsetsObjectString = [NSString stringWithFormat:OS_JS_SAFE_AREA_INSETS_OBJ,top, bottom, right, left]; - NSString *insetsString = [NSString stringWithFormat:@"\n\n\ + UIWindow *keyWindow = UIApplication.sharedApplication.keyWindow; + if (!keyWindow) { + return newHTML; + } + CGFloat top = keyWindow.safeAreaInsets.top; + CGFloat bottom = keyWindow.safeAreaInsets.bottom; + CGFloat right = keyWindow.safeAreaInsets.right; + CGFloat left = keyWindow.safeAreaInsets.left; + NSString *safeAreaInsetsObjectString = [NSString stringWithFormat:OS_JS_SAFE_AREA_INSETS_OBJ,top, bottom, right, left]; + NSString *insetsString = [NSString stringWithFormat:@"\n\n\ ",safeAreaInsetsObjectString]; - [newHTML appendString: insetsString]; - } + [newHTML appendString: insetsString]; return newHTML; } @@ -367,17 +365,14 @@ - (void)addConstraintsForMessage { // The safe area represents the anchors that are not obscurable by UI such // as a notch or a rounded corner on newer iOS devices like iPhone X - // Note that Safe Area layout guides were only introduced in iOS 11 - if (@available(iOS 11, *)) { - if (!self.isFullscreen) { - let safeArea = self.view.safeAreaLayoutGuide; - top = safeArea.topAnchor; - bottom = safeArea.bottomAnchor; - leading = safeArea.leadingAnchor; - trailing = safeArea.trailingAnchor; - center = safeArea.centerXAnchor; - height = safeArea.heightAnchor; - } + if (!self.isFullscreen) { + let safeArea = self.view.safeAreaLayoutGuide; + top = safeArea.topAnchor; + bottom = safeArea.bottomAnchor; + leading = safeArea.leadingAnchor; + trailing = safeArea.trailingAnchor; + center = safeArea.centerXAnchor; + height = safeArea.heightAnchor; } CGRect mainBounds = [OneSignalCoreHelper getScreenBounds]; @@ -419,11 +414,9 @@ - (void)addConstraintsForMessage { double bannerHeight = self.message.height.doubleValue + (2.0f * marginSpacing); double bannerMessageY = mainBounds.size.height - bannerHeight; switch (self.message.position) { - case OSInAppMessageDisplayPositionTop: - if (@available(iOS 11, *)) { - UIEdgeInsets safeAreaInsets = self.view.window.safeAreaInsets; - bannerHeight += safeAreaInsets.top + safeAreaInsets.bottom; - } + case OSInAppMessageDisplayPositionTop: { + UIEdgeInsets safeAreaInsets = self.view.window.safeAreaInsets; + bannerHeight += safeAreaInsets.top + safeAreaInsets.bottom; double statusBarHeight = UIApplication.sharedApplication.statusBarFrame.size.height; bannerHeight += statusBarHeight; self.view.window.frame = CGRectMake(0, 0, bannerWidth, bannerHeight); @@ -434,12 +427,11 @@ - (void)addConstraintsForMessage { self.panVerticalConstraint = [self.messageView.topAnchor constraintEqualToAnchor:top constant:(self.useHeightMargin ? marginSpacing : 0)]; break; - case OSInAppMessageDisplayPositionBottom: - if (@available(iOS 11, *)) { - UIEdgeInsets safeAreaInsets = self.view.window.safeAreaInsets; - bannerHeight += safeAreaInsets.top + safeAreaInsets.bottom; - bannerMessageY = mainBounds.size.height - bannerHeight; - } + } + case OSInAppMessageDisplayPositionBottom: { + UIEdgeInsets safeAreaInsets = self.view.window.safeAreaInsets; + bannerHeight += safeAreaInsets.top + safeAreaInsets.bottom; + bannerMessageY = mainBounds.size.height - bannerHeight; self.view.window.frame = CGRectMake(0, bannerMessageY, bannerWidth, bannerHeight); self.initialYConstraint = [self.messageView.topAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:8.0f]; @@ -448,15 +440,14 @@ - (void)addConstraintsForMessage { self.panVerticalConstraint = [self.messageView.bottomAnchor constraintEqualToAnchor:bottom constant:(self.useHeightMargin ? -marginSpacing : 0)]; break; + } case OSInAppMessageDisplayPositionFullScreen: case OSInAppMessageDisplayPositionCenterModal: self.view.window.frame = mainBounds; NSLayoutAnchor *centerYanchor = self.view.centerYAnchor; - if (@available(iOS 11, *)) { - if (!self.isFullscreen) { - let safeArea = self.view.safeAreaLayoutGuide; - centerYanchor = safeArea.centerYAnchor; - } + if (!self.isFullscreen) { + let safeArea = self.view.safeAreaLayoutGuide; + centerYanchor = safeArea.centerYAnchor; } self.initialYConstraint = [self.messageView.centerYAnchor constraintEqualToAnchor:centerYanchor constant:0.0f]; diff --git a/iOS_SDK/OneSignalSDK/OneSignalLocation/OneSignalLocationManager.m b/iOS_SDK/OneSignalSDK/OneSignalLocation/OneSignalLocationManager.m index 2bea4922d..9fc2403aa 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalLocation/OneSignalLocationManager.m +++ b/iOS_SDK/OneSignalSDK/OneSignalLocation/OneSignalLocationManager.m @@ -300,8 +300,7 @@ + (void)internalGetLocation:(bool)prompt fallbackToSettings:(BOOL)fallback { #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [locationManager performSelector:NSSelectorFromString(@"requestAlwaysAuthorization")]; #pragma clang diagnostic pop - if ([OSDeviceUtils isIOSVersionGreaterThanOrEqual:@"9.0"]) - [locationManager setValue:@YES forKey:@"allowsBackgroundLocationUpdates"]; + [locationManager setValue:@YES forKey:@"allowsBackgroundLocationUpdates"]; } else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) { diff --git a/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UIApplicationDelegate+OneSignalNotifications.m b/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UIApplicationDelegate+OneSignalNotifications.m index f319b4896..a842c9f34 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UIApplicationDelegate+OneSignalNotifications.m +++ b/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UIApplicationDelegate+OneSignalNotifications.m @@ -38,9 +38,8 @@ #import #import "OSMacros.h" -// This class hooks into the UIApplicationDelegate selectors to receive iOS 9 and older events. -// - UNUserNotificationCenter is used for iOS 10 -// - Orignal implementations are called so other plugins and the developers AppDelegate is still called. +// Hooks notification registration and background delivery selectors. +// Original implementations are called so other plugins and the app delegate still receive them. @implementation OneSignalNotificationsAppDelegate @@ -69,9 +68,8 @@ - (void) setOneSignalDelegate:(id)delegate { Class newClass = [OneSignalNotificationsAppDelegate class]; - // Need to keep this one for iOS 10 for content-available notifiations when the app is not in focus - // iOS 10 doesn't fire a selector on UNUserNotificationCenter in this cases most likely becuase - // UNNotificationServiceExtension (mutable-content) and UNNotificationContentExtension (with category) replaced it. + // Background content-available notifications are delivered through UIApplicationDelegate, + // not UNUserNotificationCenterDelegate. injectSelector( delegateClass, @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:), @@ -149,9 +147,7 @@ - (void)oneSignalDidFailRegisterForRemoteNotification:(UIApplication*)app error: // Fires when a notication is opened or recieved while the app is in focus. // - Also fires when the app is in the background and a notificaiton with content-available=1 is received. -// NOTE: completionHandler must only be called once! -// iOS 10 - This crashes the app if it is called twice! Crash will happen when the app is resumed. -// iOS 9 - Does not have this issue. +// NOTE: completionHandler must only be called once. - (void) oneSignalReceiveRemoteNotification:(UIApplication*)application UserInfo:(NSDictionary*)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult)) completionHandler { [OneSignalNotificationsAppDelegate traceCall:@"oneSignalReceiveRemoteNotification:UserInfo:fetchCompletionHandler:"]; SwizzlingForwarder *forwarder = [[SwizzlingForwarder alloc] diff --git a/iOS_SDK/OneSignalSDK/OneSignalNotifications/NotificationSettings/OneSignalNotificationSettings.h b/iOS_SDK/OneSignalSDK/OneSignalNotifications/NotificationSettings/OneSignalNotificationSettings.h index 6f4850b19..fe654cbac 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalNotifications/NotificationSettings/OneSignalNotificationSettings.h +++ b/iOS_SDK/OneSignalSDK/OneSignalNotifications/NotificationSettings/OneSignalNotificationSettings.h @@ -39,8 +39,6 @@ typedef void(^OSUserResponseBlock)(BOOL accepted); - (void)getNotificationPermissionState:(void (^)(OSPermissionStateInternal *subscriptionState))completionHandler; - (void)promptForNotifications:(OSUserResponseBlock)block; - (void)registerForProvisionalAuthorization:(OSUserResponseBlock)block; -// Only used for iOS 9 -- (void)onNotificationPromptResponse:(int)notificationTypes; +(dispatch_queue_t)getQueue; @end diff --git a/iOS_SDK/OneSignalSDK/OneSignalNotifications/NotificationSettings/OneSignalNotificationSettings.m b/iOS_SDK/OneSignalSDK/OneSignalNotifications/NotificationSettings/OneSignalNotificationSettings.m index 0a2db39c4..86bafd846 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalNotifications/NotificationSettings/OneSignalNotificationSettings.m +++ b/iOS_SDK/OneSignalSDK/OneSignalNotifications/NotificationSettings/OneSignalNotificationSettings.m @@ -32,7 +32,6 @@ #import "OneSignalCommonDefines.h" #import "OSNotificationsManager.h" -#import #import "OSMacros.h" #import @@ -87,12 +86,10 @@ - (void)getNotificationPermissionState:(void (^)(OSPermissionStateInternal *subs + (settings.alertSetting == UNNotificationSettingEnabled ? 4 : 0) + (settings.lockScreenSetting == UNNotificationSettingEnabled ? 8 : 0); - // check if using provisional notifications - if ([OSDeviceUtils isIOSVersionGreaterThanOrEqual:@"12.0"] && settings.authorizationStatus == provisionalStatus) + if (settings.authorizationStatus == provisionalStatus) status.notificationTypes += PROVISIONAL_UNAUTHORIZATIONOPTION; - // also check if 'deliver quietly' is enabled. - if ([OSDeviceUtils isIOSVersionGreaterThanOrEqual:@"10.0"] && settings.notificationCenterSetting == UNNotificationSettingEnabled) + if (settings.notificationCenterSetting == UNNotificationSettingEnabled) status.notificationTypes += 16; self.useCachedStatus = true; @@ -156,7 +153,7 @@ - (void)promptForNotifications:(void(^)(BOOL accepted))completionHandler { UNAuthorizationOptions options = (UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNAuthorizationOptionBadge); - if ([OSDeviceUtils isIOSVersionGreaterThanOrEqual:@"12.0"] && [OSNotificationsManager providesAppNotificationSettings]) { + if ([OSNotificationsManager providesAppNotificationSettings]) { options += PROVIDES_SETTINGS_UNAUTHORIZATIONOPTION; } @@ -167,11 +164,6 @@ - (void)promptForNotifications:(void(^)(BOOL accepted))completionHandler { } - (void)registerForProvisionalAuthorization:(OSUserResponseBlock)block { - - if ([OSDeviceUtils isIOSVersionLessThan:@"12.0"]) { - return; - } - OSPermissionStateInternal *state = [self getNotificationPermissionState]; //don't register for provisional if the user has already accepted the prompt @@ -197,8 +189,4 @@ - (void)registerForProvisionalAuthorization:(OSUserResponseBlock)block { [center requestAuthorizationWithOptions:options completionHandler:responseBlock]; } -// Ignore these 2 events, promptForNotifications: already takes care of these. -// Only iOS 9 -- (void)onNotificationPromptResponse:(int)notificationTypes { } - @end diff --git a/iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.m b/iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.m index 482b7fdcd..6e70adddf 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.m +++ b/iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.m @@ -351,10 +351,7 @@ + (void)requestPermission:(OSUserResponseBlock)block fallbackToSettings:(BOOL)fa } + (void)registerForProvisionalAuthorization:(OSUserResponseBlock)block { - if ([OSDeviceUtils isIOSVersionGreaterThanOrEqual:@"12.0"]) - [self.osNotificationSettings registerForProvisionalAuthorization:block]; - else - [OneSignalLog onesignalLog:ONE_S_LL_WARN message:@"registerForProvisionalAuthorization is only available in iOS 12+."]; + [self.osNotificationSettings registerForProvisionalAuthorization:block]; } // Checks to see if we should register for APNS' new Provisional authorization @@ -390,11 +387,6 @@ + (void)setProvidesNotificationSettingsView:(BOOL)providesView { //presents the settings page to control/customize push notification settings + (void)presentAppSettings { - - //only supported in 10+ - if ([OSDeviceUtils isIOSVersionLessThan:@"10.0"]) - return; - let url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; if (!url) @@ -522,18 +514,11 @@ + (void)removePermissionObserver:(NSObject*)ob // User just responed to the iOS native notification permission prompt. + (void)updateNotificationTypes:(int)notificationTypes { [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"updateNotificationTypes called: %d", notificationTypes]]; - - // TODO: Dropped support, can remove below? - if ([OSDeviceUtils isIOSVersionLessThan:@"10.0"]) - [OneSignalUserDefaults.initStandard saveBoolForKey:OSUD_WAS_NOTIFICATION_PROMPT_ANSWERED_TO withValue:true]; - + BOOL startedRegister = [OSNotificationsManager registerForAPNsToken]; [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"startedRegister: %d", startedRegister]]; - - // TODO: Dropped support, can remove below? - [self.osNotificationSettings onNotificationPromptResponse:notificationTypes]; // iOS 9 only - + // TODO: This can be called before the User Manager sets itself as the delegate [self sendNotificationTypesUpdateToDelegate]; } @@ -602,10 +587,8 @@ + (void)setLastnonActiveMessageId:(NSString*)value { _lastnonActiveMessageId = v // Entry point for the following: -// - 1. (iOS all) - Opening notifications -// - 2. Notification received -// - 2A. iOS 9 - Notification received while app is in focus. -// - 2B. iOS 10 - Notification received/displayed while app is in focus. +// - Opening notifications +// - Receiving notifications while the app is in focus // isActive is not always true for when the application is on foreground, we need differentiation // between foreground and isActive + (void)notificationReceived:(NSDictionary*)messageDict wasOpened:(BOOL)opened { @@ -646,7 +629,7 @@ + (void)notificationReceived:(NSDictionary*)messageDict wasOpened:(BOOL)opened { // Call Action Block [self handleNotificationOpened:messageDict actionType:type]; - } else if (isPreview && [OSDeviceUtils isIOSVersionGreaterThanOrEqual:@"10.0"]) { + } else if (isPreview) { let notification = [OSNotification parseWithApns:messageDict]; [self handleIAMPreview:notification]; } diff --git a/iOS_SDK/OneSignalSDK/OneSignalUserTests/Executors/SubscriptionUpdateRaceTests.swift b/iOS_SDK/OneSignalSDK/OneSignalUserTests/Executors/SubscriptionUpdateRaceTests.swift index 6726ff1d8..0517b6d8b 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalUserTests/Executors/SubscriptionUpdateRaceTests.swift +++ b/iOS_SDK/OneSignalSDK/OneSignalUserTests/Executors/SubscriptionUpdateRaceTests.swift @@ -139,6 +139,7 @@ final class SubscriptionUpdateRaceTests: XCTestCase { XCTAssertFalse(sentMinus19, "Must not send stale enabled:false / notification_types:-19 after grant") XCTAssertTrue(allSubscribed, "All executed UpdateSubscription payloads should reflect the live subscribed model") XCTAssertEqual(updateRequests.count, 1, "Unsent updates for the same subscription should be coalesced") + waitForUpdateRequestQueueToDrain() } /** @@ -202,11 +203,9 @@ final class SubscriptionUpdateRaceTests: XCTestCase { } XCTAssertEqual(client.startedRequests.count, 2, "Pending follow-up should send after in-flight completes") - let secondPayload = try XCTUnwrap( - (client.startedRequests[1] as? OSRequestUpdateSubscription)?.parameters?["subscription"] as? [String: Any] - ) - XCTAssertEqual(secondPayload["notification_types"] as? Int, subscribedNotificationTypes) - XCTAssertEqual(secondPayload["enabled"] as? Bool, true) + try assertSubscribedPayload(client.startedRequests[1]) + waitForCompletedUpdateRequests(client, expectedCount: 2) + waitForUpdateRequestQueueToDrain() } /** @@ -265,6 +264,7 @@ final class SubscriptionUpdateRaceTests: XCTestCase { let lastPayload = try XCTUnwrap(updateRequests.last?.parameters?["subscription"] as? [String: Any]) XCTAssertEqual(lastPayload["notification_types"] as? Int, subscribedNotificationTypes) XCTAssertEqual(lastPayload["enabled"] as? Bool, true) + waitForUpdateRequestQueueToDrain() } // MARK: - Helpers @@ -281,4 +281,28 @@ final class SubscriptionUpdateRaceTests: XCTestCase { model.notificationTypes = notificationTypes return model } + + private func waitForUpdateRequestQueueToDrain() { + OneSignalCoreMocks.waitUntil("Subscription executor cleanup did not complete") { + let requests = OneSignalUserDefaults.initShared().getSavedCodeableData( + forKey: OS_SUBSCRIPTION_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY, + defaultValue: [] + ) as? [OSRequestUpdateSubscription] + return requests?.isEmpty == true + } + } + + private func waitForCompletedUpdateRequests(_ client: MockOneSignalClient, expectedCount: Int) { + OneSignalCoreMocks.waitUntil("Subscription update did not complete") { + client.hasCompletedRequestOfType(OSRequestUpdateSubscription.self, expectedCount: expectedCount) + } + } + + private func assertSubscribedPayload(_ request: OneSignalRequest) throws { + let payload = try XCTUnwrap( + (request as? OSRequestUpdateSubscription)?.parameters?["subscription"] as? [String: Any] + ) + XCTAssertEqual(payload["notification_types"] as? Int, subscribedNotificationTypes) + XCTAssertEqual(payload["enabled"] as? Bool, true) + } } diff --git a/iOS_SDK/OneSignalSDK/OneSignalUserTests/OneSignalUserTests.swift b/iOS_SDK/OneSignalSDK/OneSignalUserTests/OneSignalUserTests.swift index e130af24b..77efb2f8a 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalUserTests/OneSignalUserTests.swift +++ b/iOS_SDK/OneSignalSDK/OneSignalUserTests/OneSignalUserTests.swift @@ -119,17 +119,9 @@ final class OneSignalUserTests: XCTestCase { */ func testBasicCombiningUserUpdateDeltas_resultsInOneRequest() throws { /* Setup */ - - OneSignalUserManagerImpl.sharedInstance.start() - let client = MockOneSignalClient() - MockUserRequests.setDefaultCreateAnonUserResponses(with: client) - OneSignalCoreImpl.setSharedClient(client) - - // Increase flush interval to allow all the updates to batch - OSOperationRepo.sharedInstance.pollIntervalMilliseconds = 300 - - OSOperationRepo.sharedInstance.flushAndWait() + let operationRepo = OSOperationRepo.sharedInstance + startUserManagerWithPausedOperations(client: client, operationRepo: operationRepo) /* When */ @@ -168,6 +160,9 @@ final class OneSignalUserTests: XCTestCase { /* Then */ + operationRepo.paused = false + operationRepo.flushAndWait() + OneSignalCoreMocks.waitUntil("Combined property update did not complete") { client.hasCompletedRequestOfType(OSRequestUpdateProperties.self) } @@ -200,6 +195,16 @@ final class OneSignalUserTests: XCTestCase { ) } + private func startUserManagerWithPausedOperations( + client: MockOneSignalClient, + operationRepo: OSOperationRepo + ) { + MockUserRequests.setDefaultCreateAnonUserResponses(with: client) + OneSignalCoreImpl.setSharedClient(client) + operationRepo.paused = true + OneSignalUserManagerImpl.sharedInstance.start() + } + /** Unit test for the tag-merge primitive. diff --git a/iOS_SDK/OneSignalSDK/Source/OneSignal.m b/iOS_SDK/OneSignalSDK/Source/OneSignal.m index d52161428..bfdcfbfb8 100755 --- a/iOS_SDK/OneSignalSDK/Source/OneSignal.m +++ b/iOS_SDK/OneSignalSDK/Source/OneSignal.m @@ -312,7 +312,7 @@ + (void)setLaunchOptions:(nullable NSDictionary*)newLaunchOptions { } + (void)setProvidesNotificationSettingsView:(BOOL)providesView { - if (providesView && [OSDeviceUtils isIOSVersionGreaterThanOrEqual:@"12.0"]) { + if (providesView) { [OSNotificationsManager setProvidesNotificationSettingsView: providesView]; } } @@ -835,13 +835,6 @@ + (void)launchWebURL:(NSString*)openUrl { } -// Called from the app's Notification Service Extension -+ (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest*)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent { - return [OneSignalNotificationServiceExtensionHandler - didReceiveNotificationExtensionRequest:request - withMutableNotificationContent:replacementContent]; -} - // Called from the app's Notification Service Extension. Calls contentHandler() to display the notification + (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest*)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { @@ -912,20 +905,10 @@ + (void)onSessionEnding:(NSArray *)lastInfluences { End of outcome module */ -// Swizzles UIApplication class to swizzling the following: -// - UIApplication -// - setDelegate: -// - Used to swizzle all UIApplicationDelegate selectors on the passed in class. -// - Almost always this is the AppDelegate class but since UIApplicationDelegate is an "interface" this could be any class. -// - UNUserNotificationCenter -// - setDelegate: -// - For iOS 10 only, swizzle all UNUserNotificationCenterDelegate selectors on the passed in class. -// - This may or may not be set so we set our own now in registerAsUNNotificationCenterDelegate to an empty class. -// -// Note1: Do NOT move this category to it's own file. This is required so when the app developer calls OneSignal.initWithLaunchOptions this load+ -// will fire along with it. This is due to how iOS loads .m files into memory instead of classes. -// Note2: Do NOT directly add swizzled selectors to this category as if this class is loaded into the runtime twice unexpected results will occur. -// The oneSignalLoadedTagSelector: selector is used a flag to prevent double swizzling if this library is loaded twice. +// Bootstraps notification swizzling through OSNotificationsManager, including UIApplicationDelegate +// and UNUserNotificationCenterDelegate selectors available on all supported iOS versions. +// Keep this category in this file so +load runs whenever OneSignal is linked. +// The oneSignalLoadedTagSelector: marker prevents swizzling when the SDK is loaded twice. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wincomplete-implementation" @implementation UIApplication (OneSignal) diff --git a/iOS_SDK/OneSignalSDK/Source/OneSignalFramework.h b/iOS_SDK/OneSignalSDK/Source/OneSignalFramework.h index 90b8b0d8a..b5722d12b 100755 --- a/iOS_SDK/OneSignalSDK/Source/OneSignalFramework.h +++ b/iOS_SDK/OneSignalSDK/Source/OneSignalFramework.h @@ -104,10 +104,8 @@ NS_SWIFT_NAME(login(externalId:token:)); + (Class)Session NS_REFINED_FOR_SWIFT; #pragma mark Extension -// iOS 10 only -// Process from Notification Service Extension. -// Used for iOS Media Attachemtns and Action Buttons. -+ (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest* _Nonnull)request withMutableNotificationContent:(UNMutableNotificationContent* _Nullable)replacementContent __deprecated_msg("Please use didReceiveNotificationExtensionRequest:withMutableNotificationContent:withContentHandler: instead."); +// Call from a UNNotificationServiceExtension on iOS 10 and later. +// Processes media attachments and action buttons. + (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest* _Nonnull)request withMutableNotificationContent:(UNMutableNotificationContent* _Nullable)replacementContent withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler; + (UNMutableNotificationContent*)serviceExtensionTimeWillExpireRequest:(UNNotificationRequest* _Nonnull)request withMutableNotificationContent:(UNMutableNotificationContent* _Nullable)replacementContent; @end diff --git a/iOS_SDK/OneSignalSDK/Source/OneSignalJailbreakDetection.m b/iOS_SDK/OneSignalSDK/Source/OneSignalJailbreakDetection.m index 3320a8389..04e359ecf 100644 --- a/iOS_SDK/OneSignalSDK/Source/OneSignalJailbreakDetection.m +++ b/iOS_SDK/OneSignalSDK/Source/OneSignalJailbreakDetection.m @@ -22,7 +22,7 @@ // Renamed DTTJailbreakDetection.m to OneSignalJailbreakDetection.m to avoid conflicts with other libraries. -#import +#import #import "OneSignalJailbreakDetection.h" @@ -78,24 +78,6 @@ + (BOOL)isJailbroken { return YES; else if ([fileManager fileExistsAtPath:@"/usr/bin/ssh"]) return YES; - - // Omit logic below since they show warnings in the device log on iOS 9 devices. - if (NSFoundationVersionNumber > 1144.17) // NSFoundationVersionNumber_iOS_8_4 - return NO; - - // Check if the app can access outside of its sandbox - NSError *error = nil; - NSString *string = @"."; - [string writeToFile:@"/private/jailbreak.txt" atomically:YES encoding:NSUTF8StringEncoding error:&error]; - if (!error) - return YES; - else - [fileManager removeItemAtPath:@"/private/jailbreak.txt" error:nil]; - - // Check if the app can open a Cydia's URL scheme - if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]]) - return YES; - #endif return NO; diff --git a/iOS_SDK/OneSignalSDK/Source/UIApplicationDelegate+OneSignal.m b/iOS_SDK/OneSignalSDK/Source/UIApplicationDelegate+OneSignal.m index 315c13728..b559463b1 100644 --- a/iOS_SDK/OneSignalSDK/Source/UIApplicationDelegate+OneSignal.m +++ b/iOS_SDK/OneSignalSDK/Source/UIApplicationDelegate+OneSignal.m @@ -26,96 +26,17 @@ */ #import -#import +#import #import "UIApplicationDelegate+OneSignal.h" -#import "OneSignalFramework.h" -#import "OneSignalCommonDefines.h" -#import "OneSignalTracker.h" -#import "OneSignalSelectorHelpers.h" -#import "SwizzlingForwarder.h" -#import -@interface OneSignal (UN_extra) -+ (NSString*) appId; -@end - -// This class hooks into the UIApplicationDelegate selectors to receive iOS 9 and older events. -// - Orignal implementations are called so other plugins and the developers AppDelegate is still called. +// Provides the marker used to detect loading the SDK into the runtime more than once. @implementation OneSignalAppDelegate + (void) oneSignalLoadedTagSelector {} -// A Set to keep track of which classes we have already swizzled so we only -// swizzle each one once. If we swizzled more than once then this will create -// an infinite loop, this includes swizzling with ourselves but also with -// another SDK that swizzles. -static NSMutableSet* swizzledClasses; - -- (void) setOneSignalDelegate:(id)delegate { - [OneSignalAppDelegate traceCall:@"setOneSignalDelegate:"]; - [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"ONESIGNAL setOneSignalDelegate CALLED: %@", delegate]]; - - if (swizzledClasses == nil) - swizzledClasses = [NSMutableSet new]; - - Class delegateClass = [delegate class]; - - if (delegate == nil || [OneSignalAppDelegate swizzledClassInHeirarchy:delegateClass]) { - [self setOneSignalDelegate:delegate]; - return; - } - [swizzledClasses addObject:delegateClass]; - - Class newClass = [OneSignalAppDelegate class]; - // Used to track how long the app has been closed - injectSelector( - delegateClass, - @selector(applicationWillTerminate:), - newClass, - @selector(oneSignalApplicationWillTerminate:) - ); - - [self setOneSignalDelegate:delegate]; -} - -+ (BOOL)swizzledClassInHeirarchy:(Class)delegateClass { - if ([swizzledClasses containsObject:delegateClass]) { - [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"OneSignal already swizzled %@", NSStringFromClass(delegateClass)]]; - return true; - } - Class superClass = class_getSuperclass(delegateClass); - while(superClass) { - if ([swizzledClasses containsObject:superClass]) { - [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"OneSignal already swizzled %@ in super class: %@", NSStringFromClass(delegateClass), NSStringFromClass(superClass)]]; - return true; - } - superClass = class_getSuperclass(superClass); - } - return false; -} - --(void)oneSignalApplicationWillTerminate:(UIApplication *)application { - [OneSignalAppDelegate traceCall:@"oneSignalApplicationWillTerminate:"]; - - if ([OneSignal appId]) - [OneSignalTracker onFocus:YES]; - - SwizzlingForwarder *forwarder = [[SwizzlingForwarder alloc] - initWithTarget:self - withYourSelector:@selector( - oneSignalApplicationWillTerminate: - ) - withOriginalSelector:@selector( - applicationWillTerminate: - ) - ]; - [forwarder invokeWithArgs:@[application]]; -} - -// Used to log all calls, also used in unit tests to observer -// the OneSignalAppDelegate selectors get called. +// Used by the test overrider that verifies marker calls. +(void) traceCall:(NSString*)selector { [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:selector]; } diff --git a/iOS_SDK/OneSignalSDK/SwiftPM/Public/Headers/OneSignal/OneSignal.h b/iOS_SDK/OneSignalSDK/SwiftPM/Public/Headers/OneSignal/OneSignal.h deleted file mode 100755 index a274bcbdf..000000000 --- a/iOS_SDK/OneSignalSDK/SwiftPM/Public/Headers/OneSignal/OneSignal.h +++ /dev/null @@ -1,631 +0,0 @@ -/** - Modified MIT License - - Copyright 2017 OneSignal - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - 1. The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - 2. All copies of substantial portions of the Software may only be used in connection - with services provided by OneSignal. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -/** - ### Setting up the SDK ### - Follow the documentation from https://documentation.onesignal.com/docs/ios-sdk-setupto setup OneSignal in your app. - - ### API Reference ### - Follow the documentation from https://documentation.onesignal.com/docs/ios-sdk-api for a detailed explanation of the API. - - ### Troubleshoot ### - Follow the documentation from https://documentation.onesignal.com/docs/troubleshooting-ios to fix common problems. - - For help on how to upgrade your code from 1.* SDK to 2.*: https://documentation.onesignal.com/docs/upgrading-to-ios-sdk-20 - - ### More ### - iOS Push Cert: https://documentation.onesignal.com/docs/generating-an-ios-push-certificate -*/ - -#import -#import - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wstrict-prototypes" -#pragma clang diagnostic ignored "-Wnullability-completeness" - -/* The action type associated to an OSNotificationAction object */ -typedef NS_ENUM(NSUInteger, OSNotificationActionType) { - OSNotificationActionTypeOpened, - OSNotificationActionTypeActionTaken -}; - -@interface OSNotificationAction : NSObject - -/* The type of the notification action */ -@property(readonly)OSNotificationActionType type; - -/* The ID associated with the button tapped. NULL when the actionType is NotificationTapped */ -@property(readonly, nullable)NSString* actionId; - -@end - -/* OneSignal OSNotification */ -@interface OSNotification : NSObject - -/* Unique Message Identifier */ -@property(readonly, nullable)NSString* notificationId; - -/* Unique Template Identifier */ -@property(readonly, nullable)NSString* templateId; - -/* Name of Template */ -@property(readonly, nullable)NSString* templateName; - -/* True when the key content-available is set to 1 in the apns payload. - content-available is used to wake your app when the payload is received. - See Apple's documenation for more details. - https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application -*/ -@property(readonly)BOOL contentAvailable; - -/* True when the key mutable-content is set to 1 in the apns payload. - mutable-content is used to wake your Notification Service Extension to modify a notification. - See Apple's documenation for more details. - https://developer.apple.com/documentation/usernotifications/unnotificationserviceextension - */ -@property(readonly, getter=hasMutableContent)BOOL mutableContent; - -/* - Notification category key previously registered to display with. - This overrides OneSignal's actionButtons. - See Apple's documenation for more details. - https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/SupportingNotificationsinYourApp.html#//apple_ref/doc/uid/TP40008194-CH4-SW26 -*/ -@property(readonly, nullable)NSString* category; - -/* The badge assigned to the application icon */ -@property(readonly)NSInteger badge; -@property(readonly)NSInteger badgeIncrement; - -/* The sound parameter passed to the notification - By default set to UILocalNotificationDefaultSoundName */ -@property(readonly, nullable)NSString* sound; - -/* Main push content */ -@property(readonly, nullable)NSString* title; -@property(readonly, nullable)NSString* subtitle; -@property(readonly, nullable)NSString* body; - -/* Web address to launch within the app via a WKWebView */ -@property(readonly, nullable)NSString* launchURL; - -/* Additional key value properties set within the payload */ -@property(readonly, nullable)NSDictionary* additionalData; - -/* iOS 10+ : Attachments sent as part of the rich notification */ -@property(readonly, nullable)NSDictionary* attachments; - -/* Action buttons passed */ -@property(readonly, nullable)NSArray *actionButtons; - -/* Holds the original payload received - Keep the raw value for users that would like to root the push */ -@property(readonly, nonnull)NSDictionary *rawPayload; - -/* iOS 10+ : Groups notifications into threads */ -@property(readonly, nullable)NSString *threadId; - -/* iOS 15+ : Relevance Score for notification summary */ -@property(readonly, nullable)NSNumber *relevanceScore; - -/* iOS 15+ : Interruption Level */ -@property(readonly)NSString *interruptionLevel; - -@property(readonly, nullable)NSString *collapseId; - -/* Parses an APNS push payload into a OSNotification object. - Useful to call from your NotificationServiceExtension when the - didReceiveNotificationRequest:withContentHandler: method fires. */ -+ (instancetype)parseWithApns:(nonnull NSDictionary*)message; - -/* Convert object into a custom Dictionary / JSON Object */ -- (NSDictionary* _Nonnull)jsonRepresentation; - -/* Convert object into an NSString that can be convertible into a custom Dictionary / JSON Object */ -- (NSString* _Nonnull)stringify; - -@end - -@interface OSNotificationOpenedResult : NSObject - -@property(readonly, nonnull)OSNotification* notification; -@property(readonly, nonnull)OSNotificationAction *action; - -/* Convert object into an NSString that can be convertible into a custom Dictionary / JSON Object */ -- (NSString* _Nonnull)stringify; - -// Convert the class into a NSDictionary -- (NSDictionary *_Nonnull)jsonRepresentation; - -@end; - -@interface OSInAppMessage : NSObject - -@property (strong, nonatomic, nonnull) NSString *messageId; - -// Convert the object into a NSDictionary -- (NSDictionary *_Nonnull)jsonRepresentation; - -@end - -@interface OSInAppMessageOutcome : NSObject - -@property (strong, nonatomic, nonnull) NSString *name; -@property (strong, nonatomic, nonnull) NSNumber *weight; -@property (nonatomic) BOOL unique; - -// Convert the class into a NSDictionary -- (NSDictionary *_Nonnull)jsonRepresentation; - -@end - -@interface OSInAppMessageTag : NSObject - -@property (strong, nonatomic, nullable) NSDictionary *tagsToAdd; -@property (strong, nonatomic, nullable) NSArray *tagsToRemove; - -// Convert the class into a NSDictionary -- (NSDictionary *_Nonnull)jsonRepresentation; - -@end - -@interface OSInAppMessageAction : NSObject - -// The action name attached to the IAM action -@property (strong, nonatomic, nullable) NSString *clickName; - -// The URL (if any) that should be opened when the action occurs -@property (strong, nonatomic, nullable) NSURL *clickUrl; - -//UUID for the page in an IAM Carousel -@property (strong, nonatomic, nullable) NSString *pageId; - -// Whether or not the click action is first click on the IAM -@property (nonatomic) BOOL firstClick; - -// Whether or not the click action dismisses the message -@property (nonatomic) BOOL closesMessage; - -// The outcome to send for this action -@property (strong, nonatomic, nullable) NSArray *outcomes; - -// The tags to send for this action -@property (strong, nonatomic, nullable) OSInAppMessageTag *tags; - -// Convert the class into a NSDictionary -- (NSDictionary *_Nonnull)jsonRepresentation; - -@end - -@protocol OSInAppMessageDelegate -@optional -- (void)handleMessageAction:(OSInAppMessageAction * _Nonnull)action NS_SWIFT_NAME(handleMessageAction(action:)); -@end - -@protocol OSInAppMessageLifecycleHandler -@optional -- (void)onWillDisplayInAppMessage:(OSInAppMessage *)message; -- (void)onDidDisplayInAppMessage:(OSInAppMessage *)message; -- (void)onWillDismissInAppMessage:(OSInAppMessage *)message; -- (void)onDidDismissInAppMessage:(OSInAppMessage *)message; -@end - -// Pass in nil means a notification will not display -typedef void (^OSNotificationDisplayResponse)(OSNotification* _Nullable notification); -/* OneSignal Influence Types */ -typedef NS_ENUM(NSUInteger, OSInfluenceType) { - DIRECT, - INDIRECT, - UNATTRIBUTED, - DISABLED -}; -/* OneSignal Influence Channels */ -typedef NS_ENUM(NSUInteger, OSInfluenceChannel) { - IN_APP_MESSAGE, - NOTIFICATION, -}; - -@interface OSOutcomeEvent : NSObject - -// Session enum (DIRECT, INDIRECT, UNATTRIBUTED, or DISABLED) to determine code route and request params -@property (nonatomic) OSInfluenceType session; - -// Notification ids for the current session -@property (strong, nonatomic, nullable) NSArray *notificationIds; - -// Id or name of the event -@property (strong, nonatomic, nonnull) NSString *name; - -// Time of the event occurring -@property (strong, nonatomic, nonnull) NSNumber *timestamp; - -// A weight to attach to the outcome name -@property (strong, nonatomic, nonnull) NSDecimalNumber *weight; - -// Convert the object into a NSDictionary -- (NSDictionary * _Nonnull)jsonRepresentation; - -@end - -typedef NS_ENUM(NSInteger, OSNotificationPermission) { - // The user has not yet made a choice regarding whether your app can show notifications. - OSNotificationPermissionNotDetermined = 0, - - // The application is not authorized to post user notifications. - OSNotificationPermissionDenied, - - // The application is authorized to post user notifications. - OSNotificationPermissionAuthorized, - - // the application is only authorized to post Provisional notifications (direct to history) - OSNotificationPermissionProvisional, - - // the application is authorized to send notifications for 8 hours. Only used by App Clips. - OSNotificationPermissionEphemeral -}; - -// Permission Classes -@interface OSPermissionState : NSObject - -@property (readonly, nonatomic) BOOL reachable; -@property (readonly, nonatomic) BOOL hasPrompted; -@property (readonly, nonatomic) BOOL providesAppNotificationSettings; -@property (readonly, nonatomic) OSNotificationPermission status; -- (NSDictionary* _Nonnull)toDictionary; - -@end - -@interface OSPermissionStateChanges : NSObject - -@property (readonly, nonnull) OSPermissionState* to; -@property (readonly, nonnull) OSPermissionState* from; -- (NSDictionary* _Nonnull)toDictionary; - -@end - -// Subscription Classes -@interface OSSubscriptionState : NSObject - -@property (readonly, nonatomic) BOOL isSubscribed; // (yes only if userId, pushToken, and setSubscription exists / are true) -@property (readonly, nonatomic) BOOL isPushDisabled; // returns value of disablePush. -@property (readonly, nonatomic, nullable) NSString* userId; // AKA OneSignal PlayerId -@property (readonly, nonatomic, nullable) NSString* pushToken; // AKA Apple Device Token -- (NSDictionary* _Nonnull)toDictionary; - -@end - -@interface OSSubscriptionStateChanges : NSObject -@property (readonly, nonnull) OSSubscriptionState* to; -@property (readonly, nonnull) OSSubscriptionState* from; -- (NSDictionary* _Nonnull)toDictionary; -@end - -@interface OSEmailSubscriptionState : NSObject -@property (readonly, nonatomic, nullable) NSString *emailUserId; // The new Email user ID -@property (readonly, nonatomic, nullable) NSString *emailAddress; -@property (readonly, nonatomic) BOOL isSubscribed; -- (NSDictionary* _Nonnull)toDictionary; -@end - -@interface OSEmailSubscriptionStateChanges : NSObject -@property (readonly, nonnull) OSEmailSubscriptionState* to; -@property (readonly, nonnull) OSEmailSubscriptionState* from; -- (NSDictionary* _Nonnull)toDictionary; -@end - -@interface OSSMSSubscriptionState : NSObject -@property (readonly, nonatomic, nullable) NSString* smsUserId; -@property (readonly, nonatomic, nullable) NSString *smsNumber; -@property (readonly, nonatomic) BOOL isSubscribed; -- (NSDictionary* _Nonnull)toDictionary; -@end - -@interface OSSMSSubscriptionStateChanges : NSObject -@property (readonly, nonnull) OSSMSSubscriptionState* to; -@property (readonly, nonnull) OSSMSSubscriptionState* from; -- (NSDictionary* _Nonnull)toDictionary; -@end - -@protocol OSPermissionObserver -- (void)onOSPermissionChanged:(OSPermissionStateChanges* _Nonnull)stateChanges; -@end - -@protocol OSSubscriptionObserver -- (void)onOSSubscriptionChanged:(OSSubscriptionStateChanges* _Nonnull)stateChanges; -@end - -@protocol OSEmailSubscriptionObserver -- (void)onOSEmailSubscriptionChanged:(OSEmailSubscriptionStateChanges* _Nonnull)stateChanges; -@end - -@protocol OSSMSSubscriptionObserver -- (void)onOSSMSSubscriptionChanged:(OSSMSSubscriptionStateChanges* _Nonnull)stateChanges; -@end - -@interface OSDeviceState : NSObject -/** - * Get the app's notification permission - * @return false if the user disabled notifications for the app, otherwise true - */ -@property (readonly) BOOL hasNotificationPermission; -/** - * Get whether the user is subscribed to OneSignal notifications or not - * @return false if the user is not subscribed to OneSignal notifications, otherwise true - */ -@property (readonly) BOOL isPushDisabled; -/** - * Get whether the user is subscribed - * @return true if isNotificationEnabled, isUserSubscribed, getUserId and getPushToken are true, otherwise false - */ -@property (readonly) BOOL isSubscribed; -/** - * Get the user notification permision status - * @return OSNotificationPermission -*/ -@property (readonly) OSNotificationPermission notificationPermissionStatus; -/** - * Get user id from registration (player id) - * @return user id if user is registered, otherwise null - */ -@property (readonly, nullable) NSString* userId; -/** - * Get apple deice push token - * @return push token if available, otherwise null - */ -@property (readonly, nullable) NSString* pushToken; -/** - * Get the user email id - * @return email id if user address was registered, otherwise null - */ -@property (readonly, nullable) NSString* emailUserId; -/** - * Get the user email - * @return email address if set, otherwise null - */ -@property (readonly, nullable) NSString* emailAddress; - -@property (readonly) BOOL isEmailSubscribed; - -/** - * Get the user sms id - * @return sms id if user sms number was registered, otherwise null - */ -@property (readonly, nullable) NSString* smsUserId; -/** - * Get the user sms number, number may start with + and continue with numbers or contain only numbers - * e.g: +11231231231 or 11231231231 - * @return sms number if set, otherwise null - */ -@property (readonly, nullable) NSString* smsNumber; - -@property (readonly) BOOL isSMSSubscribed; - -// Convert the class into a NSDictionary -- (NSDictionary *_Nonnull)jsonRepresentation; - -@end - -typedef void (^OSWebOpenURLResultBlock)(BOOL shouldOpen); - -/*Block for generic results on success and errors on failure*/ -typedef void (^OSResultSuccessBlock)(NSDictionary* result); -typedef void (^OSFailureBlock)(NSError* error); - -/*Block for handling outcome event being sent successfully*/ -typedef void (^OSSendOutcomeSuccess)(OSOutcomeEvent* outcome); - -// ======= OneSignal Class Interface ========= -@interface OneSignal : NSObject - -extern NSString* const ONESIGNAL_VERSION; - -+ (NSString*)appId; -+ (NSString* _Nonnull)sdkVersionRaw; -+ (NSString* _Nonnull)sdkSemanticVersion; - -+ (void)disablePush:(BOOL)disable; - -// Only used for wrapping SDKs, such as Unity, Cordova, Xamarin, etc. -+ (void)setMSDKType:(NSString* _Nonnull)type; - -#pragma mark Initialization -+ (void)setAppId:(NSString* _Nonnull)newAppId; -+ (void)initWithLaunchOptions:(NSDictionary* _Nullable)launchOptions; -+ (void)setLaunchURLsInApp:(BOOL)launchInApp; -+ (void)setProvidesNotificationSettingsView:(BOOL)providesView; - -#pragma mark Logging -typedef NS_ENUM(NSUInteger, ONE_S_LOG_LEVEL) { - ONE_S_LL_NONE, - ONE_S_LL_FATAL, - ONE_S_LL_ERROR, - ONE_S_LL_WARN, - ONE_S_LL_INFO, - ONE_S_LL_DEBUG, - ONE_S_LL_VERBOSE -}; - -+ (void)setLogLevel:(ONE_S_LOG_LEVEL)logLevel visualLevel:(ONE_S_LOG_LEVEL)visualLogLevel; -+ (void)onesignalLog:(ONE_S_LOG_LEVEL)logLevel message:(NSString* _Nonnull)message; - -#pragma mark Prompt For Push -typedef void(^OSUserResponseBlock)(BOOL accepted); - -+ (void)promptForPushNotificationsWithUserResponse:(OSUserResponseBlock)block; -+ (void)promptForPushNotificationsWithUserResponse:(OSUserResponseBlock)block fallbackToSettings:(BOOL)fallback; -+ (void)registerForProvisionalAuthorization:(OSUserResponseBlock)block; -+ (OSDeviceState*)getDeviceState; - -#pragma mark Privacy Consent -+ (void)consentGranted:(BOOL)granted; -// Tells your application if privacy consent is still needed from the current user -+ (BOOL)requiresUserPrivacyConsent; -+ (void)setRequiresUserPrivacyConsent:(BOOL)required; - -#pragma mark Public Handlers - -// If the completion block is not called within 25 seconds of this block being called in notificationWillShowInForegroundHandler then the completion will be automatically fired. -typedef void (^OSNotificationWillShowInForegroundBlock)(OSNotification * _Nonnull notification, OSNotificationDisplayResponse _Nonnull completion); -typedef void (^OSNotificationOpenedBlock)(OSNotificationOpenedResult * _Nonnull result); -typedef void (^OSInAppMessageClickBlock)(OSInAppMessageAction * _Nonnull action); - -+ (void)setNotificationWillShowInForegroundHandler:(OSNotificationWillShowInForegroundBlock _Nullable)block; -+ (void)setNotificationOpenedHandler:(OSNotificationOpenedBlock _Nullable)block; -+ (void)setInAppMessageClickHandler:(OSInAppMessageClickBlock _Nullable)block; -+ (void)setInAppMessageLifecycleHandler:(NSObject *_Nullable)delegate; - -#pragma mark Post Notification -+ (void)postNotification:(NSDictionary* _Nonnull)jsonData; -+ (void)postNotification:(NSDictionary* _Nonnull)jsonData onSuccess:(OSResultSuccessBlock _Nullable)successBlock onFailure:(OSFailureBlock _Nullable)failureBlock; -+ (void)postNotificationWithJsonString:(NSString* _Nonnull)jsonData onSuccess:(OSResultSuccessBlock _Nullable)successBlock onFailure:(OSFailureBlock _Nullable)failureBlock; - -#pragma mark Location -// - Request and track user's location -+ (void)promptLocation; -+ (void)setLocationShared:(BOOL)enable; -+ (BOOL)isLocationShared; - -#pragma mark NotificationService Extension -// iOS 10 only -// Process from Notification Service Extension. -// Used for iOS Media Attachemtns and Action Buttons. -+ (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest* _Nonnull)request withMutableNotificationContent:(UNMutableNotificationContent* _Nullable)replacementContent __deprecated_msg("Please use didReceiveNotificationExtensionRequest:withMutableNotificationContent:withContentHandler: instead."); -+ (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest* _Nonnull)request withMutableNotificationContent:(UNMutableNotificationContent* _Nullable)replacementContent withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler; -+ (UNMutableNotificationContent*)serviceExtensionTimeWillExpireRequest:(UNNotificationRequest* _Nonnull)request withMutableNotificationContent:(UNMutableNotificationContent* _Nullable)replacementContent; - -#pragma mark Tags -+ (void)sendTag:(NSString* _Nonnull)key value:(NSString* _Nonnull)value onSuccess:(OSResultSuccessBlock _Nullable)successBlock onFailure:(OSFailureBlock _Nullable)failureBlock; -+ (void)sendTag:(NSString* _Nonnull)key value:(NSString* _Nonnull)value; -+ (void)sendTags:(NSDictionary* _Nonnull)keyValuePair onSuccess:(OSResultSuccessBlock _Nullable)successBlock onFailure:(OSFailureBlock _Nullable)failureBlock; -+ (void)sendTags:(NSDictionary* _Nonnull)keyValuePair; -+ (void)sendTagsWithJsonString:(NSString* _Nonnull)jsonString; -+ (void)getTags:(OSResultSuccessBlock _Nullable)successBlock onFailure:(OSFailureBlock _Nullable)failureBlock; -+ (void)getTags:(OSResultSuccessBlock _Nullable)successBlock; -+ (void)deleteTag:(NSString* _Nonnull)key onSuccess:(OSResultSuccessBlock _Nullable)successBlock onFailure:(OSFailureBlock _Nullable)failureBlock; -+ (void)deleteTag:(NSString* _Nonnull)key; -+ (void)deleteTags:(NSArray* _Nonnull)keys onSuccess:(OSResultSuccessBlock _Nullable)successBlock onFailure:(OSFailureBlock _Nullable)failureBlock; -+ (void)deleteTags:(NSArray *_Nonnull)keys; -+ (void)deleteTagsWithJsonString:(NSString* _Nonnull)jsonString; - -#pragma mark Permission, Subscription, and Email Observers -NS_ASSUME_NONNULL_BEGIN - -+ (void)addPermissionObserver:(NSObject*)observer; -+ (void)removePermissionObserver:(NSObject*)observer; - -+ (void)addSubscriptionObserver:(NSObject*)observer; -+ (void)removeSubscriptionObserver:(NSObject*)observer; - -+ (void)addEmailSubscriptionObserver:(NSObject*)observer; -+ (void)removeEmailSubscriptionObserver:(NSObject*)observer; - -+ (void)addSMSSubscriptionObserver:(NSObject*)observer; -+ (void)removeSMSSubscriptionObserver:(NSObject*)observer; -NS_ASSUME_NONNULL_END - -#pragma mark Email -// Typedefs defining completion blocks for email & simultaneous HTTP requests -typedef void (^OSEmailFailureBlock)(NSError *error); -typedef void (^OSEmailSuccessBlock)(); - -// Allows you to set the email for this user. -// Email Auth Token is a (recommended) optional parameter that should *NOT* be generated on the client. -// For security purposes, the emailAuthToken should be generated by your backend server. -// If you do not have a backend server for your application, use the version of thge setEmail: method without an emailAuthToken parameter. -+ (void)setEmail:(NSString * _Nonnull)email withEmailAuthHashToken:(NSString * _Nullable)hashToken; -+ (void)setEmail:(NSString * _Nonnull)email withEmailAuthHashToken:(NSString * _Nullable)hashToken withSuccess:(OSEmailSuccessBlock _Nullable)successBlock withFailure:(OSEmailFailureBlock _Nullable)failureBlock; - -// Sets email without an authentication token -+ (void)setEmail:(NSString * _Nonnull)email; -+ (void)setEmail:(NSString * _Nonnull)email withSuccess:(OSEmailSuccessBlock _Nullable)successBlock withFailure:(OSEmailFailureBlock _Nullable)failureBlock; - -// Logs the device out of the current email. -+ (void)logoutEmail; -+ (void)logoutEmailWithSuccess:(OSEmailSuccessBlock _Nullable)successBlock withFailure:(OSEmailFailureBlock _Nullable)failureBlock; - -#pragma mark SMS -// Typedefs defining completion blocks for SMS & simultaneous HTTP requests -typedef void (^OSSMSFailureBlock)(NSError *error); -typedef void (^OSSMSSuccessBlock)(NSDictionary *results); - -// Allows you to set the SMS for this user. SMS number may start with + and continue with numbers or contain only numbers -// e.g: +11231231231 or 11231231231 -// SMS Auth Token is a (recommended) optional parameter that should *NOT* be generated on the client. -// For security purposes, the smsAuthToken should be generated by your backend server. -// If you do not have a backend server for your application, use the version of thge setSMSNumber: method without an smsAuthToken parameter. -+ (void)setSMSNumber:(NSString * _Nonnull)smsNumber withSMSAuthHashToken:(NSString * _Nullable)hashToken; -+ (void)setSMSNumber:(NSString * _Nonnull)smsNumber withSMSAuthHashToken:(NSString * _Nullable)hashToken withSuccess:(OSSMSSuccessBlock _Nullable)successBlock withFailure:(OSSMSFailureBlock _Nullable)failureBlock; - -// Sets SMS without an authentication token -+ (void)setSMSNumber:(NSString * _Nonnull)smsNumber; -+ (void)setSMSNumber:(NSString * _Nonnull)smsNumber withSuccess:(OSSMSSuccessBlock _Nullable)successBlock withFailure:(OSSMSFailureBlock _Nullable)failureBlock; - -// Logs the device out of the current sms number. -+ (void)logoutSMSNumber; -+ (void)logoutSMSNumberWithSuccess:(OSSMSSuccessBlock _Nullable)successBlock withFailure:(OSSMSFailureBlock _Nullable)failureBlock; - -#pragma mark Language -// Typedefs defining completion blocks for updating language -typedef void (^OSUpdateLanguageFailureBlock)(NSError *error); -typedef void (^OSUpdateLanguageSuccessBlock)(); - -// Language input ISO 639-1 code representation for user input language -+ (void)setLanguage:(NSString * _Nonnull)language; -+ (void)setLanguage:(NSString * _Nonnull)language withSuccess:(OSUpdateLanguageSuccessBlock _Nullable)successBlock withFailure:(OSUpdateLanguageFailureBlock)failureBlock; - -#pragma mark External User Id -// Typedefs defining completion blocks for updating the external user id -typedef void (^OSUpdateExternalUserIdFailureBlock)(NSError *error); -typedef void (^OSUpdateExternalUserIdSuccessBlock)(NSDictionary *results); - -+ (void)setExternalUserId:(NSString * _Nonnull)externalId; -+ (void)setExternalUserId:(NSString * _Nonnull)externalId withSuccess:(OSUpdateExternalUserIdSuccessBlock _Nullable)successBlock withFailure:(OSUpdateExternalUserIdFailureBlock _Nullable)failureBlock; -+ (void)setExternalUserId:(NSString *)externalId withExternalIdAuthHashToken:(NSString *)hashToken withSuccess:(OSUpdateExternalUserIdSuccessBlock _Nullable)successBlock withFailure:(OSUpdateExternalUserIdFailureBlock _Nullable)failureBlock; -+ (void)removeExternalUserId; -+ (void)removeExternalUserId:(OSUpdateExternalUserIdSuccessBlock _Nullable)successBlock withFailure:(OSUpdateExternalUserIdFailureBlock _Nullable)failureBlock; - -#pragma mark In-App Messaging -+ (BOOL)isInAppMessagingPaused; -+ (void)pauseInAppMessages:(BOOL)pause; -+ (void)addTrigger:(NSString * _Nonnull)key withValue:(id _Nonnull)value; -+ (void)addTriggers:(NSDictionary * _Nonnull)triggers; -+ (void)removeTriggerForKey:(NSString * _Nonnull)key; -+ (void)removeTriggersForKeys:(NSArray * _Nonnull)keys; -+ (NSDictionary * _Nonnull)getTriggers; -+ (id _Nullable)getTriggerValueForKey:(NSString * _Nonnull)key; - -#pragma mark Outcomes -+ (void)sendOutcome:(NSString * _Nonnull)name; -+ (void)sendOutcome:(NSString * _Nonnull)name onSuccess:(OSSendOutcomeSuccess _Nullable)success; -+ (void)sendUniqueOutcome:(NSString * _Nonnull)name; -+ (void)sendUniqueOutcome:(NSString * _Nonnull)name onSuccess:(OSSendOutcomeSuccess _Nullable)success; -+ (void)sendOutcomeWithValue:(NSString * _Nonnull)name value:(NSNumber * _Nonnull)value; -+ (void)sendOutcomeWithValue:(NSString * _Nonnull)name value:(NSNumber * _Nonnull)value onSuccess:(OSSendOutcomeSuccess _Nullable)success; -@end - -#pragma clang diagnostic pop diff --git a/iOS_SDK/OneSignalSDK/UnitTests/InAppMessagingTests.m b/iOS_SDK/OneSignalSDK/UnitTests/InAppMessagingTests.m index dff74c78d..a0d34b605 100644 --- a/iOS_SDK/OneSignalSDK/UnitTests/InAppMessagingTests.m +++ b/iOS_SDK/OneSignalSDK/UnitTests/InAppMessagingTests.m @@ -136,38 +136,20 @@ of this software and associated documentation files (the "Software"), to deal //} // //-(void)testIphoneSimulator { -// OneSignalHelperOverrider.mockIOSVersion = 10; // [OSMessagingController removeInstance]; // let sharedInstance = OSMessagingController.sharedInstance; // XCTAssertEqualObjects(sharedInstance.class, OSMessagingController.class); //} // //-(void)testIpadSimulator { -// OneSignalHelperOverrider.mockIOSVersion = 10; // [OSMessagingController removeInstance]; // [UIDeviceOverrider setModel:@"iPad"]; // let sharedInstance = OSMessagingController.sharedInstance; // XCTAssertEqualObjects(sharedInstance.class, OSMessagingController.class); //} // -//-(void)testOldUnsupportedIphoneSimulator { -// OneSignalHelperOverrider.mockIOSVersion = 9; -// [OSMessagingController removeInstance]; -// let sharedInstance = OSMessagingController.sharedInstance; -// XCTAssertEqualObjects(sharedInstance.class, DummyOSMessagingController.class); // sharedInstance should be dummy controller -//} -// -//-(void)testOldUnsupportedIpadSimulator { -// OneSignalHelperOverrider.mockIOSVersion = 8; -// [OSMessagingController removeInstance]; -// [UIDeviceOverrider setModel:@"iPad"]; -// let sharedInstance = OSMessagingController.sharedInstance; -// XCTAssertEqualObjects(sharedInstance.class, DummyOSMessagingController.class); // sharedInstance should be dummy controller -//} -// //// This test needs to be run with Mac Catalyst as the build target //-(void)testUnsupportedCatalyst { -// OneSignalHelperOverrider.mockIOSVersion = 10; // [OSMessagingController removeInstance]; // let sharedInstance = OSMessagingController.sharedInstance; // #if TARGET_OS_MACCATALYST @@ -178,37 +160,19 @@ of this software and associated documentation files (the "Software"), to deal //} // //-(void)testRealIphone { -// OneSignalHelperOverrider.mockIOSVersion = 10; // [OSMessagingController removeInstance]; // [OneSignalHelperOverrider setSystemInfoMachine:@"iPhone9,3"]; // let sharedInstance = OSMessagingController.sharedInstance; // XCTAssertEqualObjects(sharedInstance.class, OSMessagingController.class); //} // -//-(void)testRealUnsupportedIphone { -// OneSignalHelperOverrider.mockIOSVersion = 8; -// [OSMessagingController removeInstance]; -// [OneSignalHelperOverrider setSystemInfoMachine:@"iPhone9,3"]; -// let sharedInstance = OSMessagingController.sharedInstance; -// XCTAssertEqualObjects(sharedInstance.class, DummyOSMessagingController.class); // sharedInstance should be dummy controller -//} -// //-(void)testRealIpad { -// OneSignalHelperOverrider.mockIOSVersion = 13; // [OSMessagingController removeInstance]; // [OneSignalHelperOverrider setSystemInfoMachine:@"iPad6,7"]; // let sharedInstance = OSMessagingController.sharedInstance; // XCTAssertEqualObjects(sharedInstance.class, OSMessagingController.class); //} // -//-(void)testRealUnsupportedIpad { -// OneSignalHelperOverrider.mockIOSVersion = 8; -// [OSMessagingController removeInstance]; -// [OneSignalHelperOverrider setSystemInfoMachine:@"iPad6,7"]; -// let sharedInstance = OSMessagingController.sharedInstance; -// XCTAssertEqualObjects(sharedInstance.class, DummyOSMessagingController.class); // sharedInstance should be dummy controller -//} -// //#pragma mark Message JSON Parsing Tests //-(void)testCorrectlyParsedMessageId { // XCTAssertTrue([testMessage.messageId containsString:OS_TEST_MESSAGE_ID]); diff --git a/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OneSignalHelperOverrider.h b/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OneSignalHelperOverrider.h index 73f337bf8..617fdd6d4 100644 --- a/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OneSignalHelperOverrider.h +++ b/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OneSignalHelperOverrider.h @@ -36,11 +36,8 @@ @interface OneSignalHelperOverrider : NSObject + (void)reset; -+ (void)setMockIOSVersion:(float)value; -+ (float)mockIOSVersion; + (void)runBackgroundThreads; + (void)setOverrideIsTablet:(BOOL)shouldBeTablet; + (void)setSystemInfoMachine:(NSString*) name; -+ (BOOL)overrideIsIOSVersionGreaterThanOrEqual:(NSString *)version; @end diff --git a/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OneSignalHelperOverrider.m b/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OneSignalHelperOverrider.m index acbc66d32..11de39f5c 100644 --- a/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OneSignalHelperOverrider.m +++ b/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OneSignalHelperOverrider.m @@ -42,8 +42,6 @@ // //static XCTestCase* currentTestInstance; // -//static float mockIOSVersion; -// //static bool overrideIsTablet = false; // //+ (NSString*)overrideGetSystemInfoMachine { @@ -59,8 +57,6 @@ // // injectStaticSelector([OneSignalHelperOverrider class], @selector(overrideGetAppName), [OneSignalHelper class], @selector(getAppName)); // -// injectStaticSelector([OneSignalHelperOverrider class], @selector(overrideIsIOSVersionGreaterThanOrEqual:), [OneSignalHelper class], @selector(isIOSVersionGreaterThanOrEqual:)); -// // injectStaticSelector([OneSignalHelperOverrider class], @selector(overrideDispatch_async_on_main_queue:), [OneSignalHelper class], @selector(dispatch_async_on_main_queue:)); // injectStaticSelector([OneSignalHelperOverrider class], @selector(overrideIsTablet), [OneSignalHelper class], @selector(isTablet)); // injectStaticSelector([OneSignalHelperOverrider class], @selector(overrideGetSystemInfoMachine), [OneSignalHelper class], @selector(getSystemInfoMachine)); @@ -70,14 +66,6 @@ // _systemInfoMachine = @"x86_64"; //} // -//+ (void)setMockIOSVersion:(float)value { -// mockIOSVersion = value; -//} -// -//+ (float)mockIOSVersion { -// return mockIOSVersion; -//} -// //+ (BOOL)overrideIsTablet { // return overrideIsTablet; //} @@ -90,10 +78,6 @@ // overrideIsTablet = shouldBeTablet; //} // -//+ (BOOL)overrideIsIOSVersionGreaterThanOrEqual:(NSString *)version { -// return mockIOSVersion >= [version floatValue]; -//} -// //+ (void) overrideDispatch_async_on_main_queue:(void(^)())block { // dispatch_async(serialMockMainLooper, block); //}