diff --git a/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj b/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj index 6f42d8e1a..aaa552afe 100644 --- a/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj +++ b/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj @@ -413,6 +413,8 @@ DE16C14424D3724700670EFA /* OneSignalLifecycleObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = DE16C14324D3724700670EFA /* OneSignalLifecycleObserver.m */; }; DE16C14524D3724700670EFA /* OneSignalLifecycleObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = DE16C14324D3724700670EFA /* OneSignalLifecycleObserver.m */; }; DE16C14724D3727200670EFA /* OneSignalLifecycleObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = DE16C14624D3727200670EFA /* OneSignalLifecycleObserver.h */; }; + DE16C17024D3989A00670EFA /* OneSignalLifecycleObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = DE16C14324D3724700670EFA /* OneSignalLifecycleObserver.m */; }; + DE5EFECA24D8DBF70032632D /* OSInAppMessageViewControllerOverrider.m in Sources */ = {isa = PBXBuildFile; fileRef = DE5EFEC924D8DBF70032632D /* OSInAppMessageViewControllerOverrider.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -687,6 +689,8 @@ CACBAAAB218A662B000ACAA5 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; DE16C14324D3724700670EFA /* OneSignalLifecycleObserver.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OneSignalLifecycleObserver.m; sourceTree = ""; }; DE16C14624D3727200670EFA /* OneSignalLifecycleObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OneSignalLifecycleObserver.h; sourceTree = ""; }; + DE5EFEC924D8DBF70032632D /* OSInAppMessageViewControllerOverrider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OSInAppMessageViewControllerOverrider.m; sourceTree = ""; }; + DE5EFECB24D8DC0E0032632D /* OSInAppMessageViewControllerOverrider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSInAppMessageViewControllerOverrider.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -825,6 +829,8 @@ CAAE0DFC2195216900A57402 /* OneSignalOverrider.m */, 9D348538233D2DCF00EB81C9 /* OneSignalLocationOverrider.h */, 9D348539233D2E3600EB81C9 /* OneSignalLocationOverrider.m */, + DE5EFECB24D8DC0E0032632D /* OSInAppMessageViewControllerOverrider.h */, + DE5EFEC924D8DBF70032632D /* OSInAppMessageViewControllerOverrider.m */, ); path = Shadows; sourceTree = ""; @@ -1703,6 +1709,7 @@ CAABF34D205B157B0042F8E5 /* OneSignalExtensionBadgeHandler.m in Sources */, 912412301E73342200E41FD7 /* OneSignalSelectorHelpers.m in Sources */, 91F58D851E7C88230017D24D /* OneSignalNotificationSettingsIOS10.m in Sources */, + DE16C17024D3989A00670EFA /* OneSignalLifecycleObserver.m in Sources */, CAAE0DFD2195216900A57402 /* OneSignalOverrider.m in Sources */, 912412241E73342200E41FD7 /* OneSignalLocation.m in Sources */, CA8E190B2194FE0B009DA223 /* OSMessagingControllerOverrider.m in Sources */, @@ -1777,6 +1784,7 @@ 7AFE856D2368DDB80091D6A5 /* OSFocusCallParams.m in Sources */, CA8E19082193C76D009DA223 /* OSInAppMessagingHelpers.m in Sources */, 4529DEE11FA82AB300CEAB1D /* NSBundleOverrider.m in Sources */, + DE5EFECA24D8DBF70032632D /* OSInAppMessageViewControllerOverrider.m in Sources */, 7AF986602447C13C00C36EAE /* OSInfluenceDataRepository.m in Sources */, 912412441E73342200E41FD7 /* UNUserNotificationCenter+OneSignal.m in Sources */, 03866CC12378A67B0009C1D8 /* RestClientAsserts.m in Sources */, diff --git a/iOS_SDK/OneSignalSDK/Source/OneSignalLifecycleObserver.m b/iOS_SDK/OneSignalSDK/Source/OneSignalLifecycleObserver.m index ae0f2bf6f..bf67cbfd1 100644 --- a/iOS_SDK/OneSignalSDK/Source/OneSignalLifecycleObserver.m +++ b/iOS_SDK/OneSignalSDK/Source/OneSignalLifecycleObserver.m @@ -32,8 +32,8 @@ + (void)registerLifecycleObserver { // Replacing swizzled lifecycle selectors with notification center observers for scene based Apps if (@available(iOS 13.0, *)) { NSDictionary *sceneManifest = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIApplicationSceneManifest"]; - [OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:@"registering for Scene Lifecycle notifications"]; if (sceneManifest) { + [OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:@"registering for Scene Lifecycle notifications"]; [[NSNotificationCenter defaultCenter] addObserver:[OneSignalLifecycleObserver sharedInstance] selector:@selector(didEnterBackground) name:UISceneDidEnterBackgroundNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:[OneSignalLifecycleObserver sharedInstance] selector:@selector(didBecomeActive) name:UISceneDidActivateNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:[OneSignalLifecycleObserver sharedInstance] selector:@selector(willResignActive) name:UISceneWillDeactivateNotification object:nil]; diff --git a/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OSInAppMessageViewControllerOverrider.h b/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OSInAppMessageViewControllerOverrider.h new file mode 100644 index 000000000..66cd3a55c --- /dev/null +++ b/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OSInAppMessageViewControllerOverrider.h @@ -0,0 +1,12 @@ +// +// OSInAppMessageViewControllerOverrider.h +// UnitTests +// +// Created by Elliot Mawby on 8/3/20. +// Copyright © 2020 Hiptic. All rights reserved. +// + +@interface OSInAppMessageViewControllerOverrider : NSObject + +@end + diff --git a/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OSInAppMessageViewControllerOverrider.m b/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OSInAppMessageViewControllerOverrider.m new file mode 100644 index 000000000..3f0f18ba1 --- /dev/null +++ b/iOS_SDK/OneSignalSDK/UnitTests/Shadows/OSInAppMessageViewControllerOverrider.m @@ -0,0 +1,46 @@ +/** +* Modified MIT License +* +* Copyright 2020 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. +*/ + +#import +#import "OSInAppMessageViewControllerOverrider.h" +#import "OSInAppMessageViewController.h" +#import "OneSignalSelectorHelpers.h" + +@implementation OSInAppMessageViewControllerOverrider + ++ (void)load { + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wundeclared-selector" + injectToProperClass(@selector(overrideAnimateAppearance), @selector(animateAppearance), @[], [OSInAppMessageViewControllerOverrider class], [OSInAppMessageViewController class]); + #pragma clang diagnostic pop +} + +- (void)overrideAnimateAppearance { + +} + +@end diff --git a/iOS_SDK/OneSignalSDK/UnitTests/UnitTestCommonMethods.h b/iOS_SDK/OneSignalSDK/UnitTests/UnitTestCommonMethods.h index faf56527f..ebc3a1700 100644 --- a/iOS_SDK/OneSignalSDK/UnitTests/UnitTestCommonMethods.h +++ b/iOS_SDK/OneSignalSDK/UnitTests/UnitTestCommonMethods.h @@ -40,6 +40,7 @@ NSString * serverUrlWithPath(NSString *path); + (void)setCurrentNotificationPermissionAsUnanswered; + (void)foregroundApp; + (void)backgroundApp; ++ (void)useSceneLifecycle:(BOOL)useSceneLifecycle; + (void)initOneSignal; + (void)initOneSignalAndThreadWait; + (void)runBackgroundThreads; diff --git a/iOS_SDK/OneSignalSDK/UnitTests/UnitTestCommonMethods.m b/iOS_SDK/OneSignalSDK/UnitTests/UnitTestCommonMethods.m index f5c6c99b8..12f84e8bf 100644 --- a/iOS_SDK/OneSignalSDK/UnitTests/UnitTestCommonMethods.m +++ b/iOS_SDK/OneSignalSDK/UnitTests/UnitTestCommonMethods.m @@ -215,14 +215,37 @@ + (void)initOneSignalAndThreadWait { + (void)foregroundApp { UIApplicationOverrider.currentUIApplicationState = UIApplicationStateActive; - UIApplication *sharedApp = [UIApplication sharedApplication]; - [sharedApp.delegate applicationDidBecomeActive:sharedApp]; + + if (@available(iOS 13.0, *)) { + NSDictionary *sceneManifest = [[NSBundle bundleForClass:[OneSignal class]] objectForInfoDictionaryKey:@"UIApplicationSceneManifest"]; + if (sceneManifest) { + [[NSNotificationCenter defaultCenter] postNotificationName:UISceneDidActivateNotification object:nil]; + return; + } + } + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidBecomeActiveNotification object:nil]; } + (void)backgroundApp { UIApplicationOverrider.currentUIApplicationState = UIApplicationStateBackground; - UIApplication *sharedApp = [UIApplication sharedApplication]; - [sharedApp.delegate applicationWillResignActive:sharedApp]; + if (@available(iOS 13.0, *)) { + NSDictionary *sceneManifest = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIApplicationSceneManifest"]; + if (sceneManifest) { + [[NSNotificationCenter defaultCenter] postNotificationName:UISceneWillDeactivateNotification object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:UISceneDidEnterBackgroundNotification object:nil]; + return; + } + } + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillResignActiveNotification object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil]; +} + +//Call this method before init OneSignal. Make sure not to overwrite the NSBundleDictionary in later calls. ++ (void)useSceneLifecycle:(BOOL)useSceneLifecycle { + NSMutableDictionary *currentBundleDictionary = [[NSMutableDictionary alloc] initWithDictionary:NSBundleOverrider.nsbundleDictionary]; + if (useSceneLifecycle) + [currentBundleDictionary setObject:@[@"SceneDelegate"] forKey:@"UIApplicationSceneManifest"]; + NSBundleOverrider.nsbundleDictionary = currentBundleDictionary; } + (void)setCurrentNotificationPermission:(BOOL)accepted { diff --git a/iOS_SDK/OneSignalSDK/UnitTests/UnitTests.m b/iOS_SDK/OneSignalSDK/UnitTests/UnitTests.m index 38781ccc5..a7d6f5e4b 100644 --- a/iOS_SDK/OneSignalSDK/UnitTests/UnitTests.m +++ b/iOS_SDK/OneSignalSDK/UnitTests/UnitTests.m @@ -142,8 +142,17 @@ - (void)registerForPushNotifications { - (void)backgroundApp { UIApplicationOverrider.currentUIApplicationState = UIApplicationStateBackground; - UIApplication *sharedApp = [UIApplication sharedApplication]; - [sharedApp.delegate applicationWillResignActive:sharedApp]; + if (@available(iOS 13.0, *)) { + NSDictionary *sceneManifest = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIApplicationSceneManifest"]; + if (sceneManifest) { + [[NSNotificationCenter defaultCenter] postNotificationName:UISceneWillDeactivateNotification object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:UISceneDidEnterBackgroundNotification object:nil]; + return; + } + } + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillResignActiveNotification object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil]; + } - (UNNotificationResponse*)createBasiciOSNotificationResponse { @@ -1632,13 +1641,25 @@ - (void)testFirstInitWithNotificationsAlreadyDeclined { XCTAssertEqual(OneSignalClientOverrider.networkRequestCount, 2); } -- (void)testPermissionChangedInSettingsOutsideOfApp { +- (void)testPermissionChangedInSettingsOutsideOfAppWithAppDelegate { + [self permissionChangedInSettingsOutsideOfApp:NO]; +} + +- (void)testPermissionChangedInSettingsOutsideOfAppWithSceneDelegate { + [self permissionChangedInSettingsOutsideOfApp:YES]; +} + +- (void)permissionChangedInSettingsOutsideOfApp: (BOOL)useSceneDelegate { + [UnitTestCommonMethods clearStateForAppRestart:self]; [self backgroundModesDisabledInXcode]; UNUserNotificationCenterOverrider.notifTypesOverride = 0; UNUserNotificationCenterOverrider.authorizationStatus = [NSNumber numberWithInteger:UNAuthorizationStatusDenied]; + + [UnitTestCommonMethods useSceneLifecycle: useSceneDelegate]; + [UnitTestCommonMethods initOneSignalAndThreadWait]; OSPermissionStateTestObserver* observer = [OSPermissionStateTestObserver new];