-
Notifications
You must be signed in to change notification settings - Fork 71
feat: Implement Manual SceneDelegate Support #453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
775315c
066f11f
e1ba42d
2250131
a7fc201
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
|
|
||
| #if MPARTICLE_LOCATION_DISABLE | ||
| import mParticle_Apple_SDK_NoLocation | ||
| #else | ||
| import mParticle_Apple_SDK | ||
| #endif | ||
| import XCTest | ||
|
|
||
| final class MParticleSceneDelegateTests: MParticleTestBase { | ||
|
|
||
| // MARK: - Properties | ||
|
|
||
| var testURL: URL! | ||
| var testUserActivity: NSUserActivity! | ||
|
|
||
| override func setUp() { | ||
| super.setUp() | ||
| testURL = URL(string: "myapp://test/path?param=value")! | ||
| testUserActivity = NSUserActivity(activityType: "com.test.activity") | ||
| testUserActivity.title = "Test Activity" | ||
| testUserActivity.userInfo = ["key": "value"] | ||
|
|
||
| // The implementation calls [MParticle sharedInstance], so we need to set the mock on the shared instance | ||
| MParticle.sharedInstance().appNotificationHandler = appNotificationHandler | ||
|
|
||
| // Reset mock state for each test | ||
| appNotificationHandler.continueUserActivityCalled = false | ||
| appNotificationHandler.continueUserActivityUserActivityParam = nil | ||
| appNotificationHandler.continueUserActivityRestorationHandlerParam = nil | ||
| appNotificationHandler.openURLWithOptionsCalled = false | ||
| appNotificationHandler.openURLWithOptionsURLParam = nil | ||
| appNotificationHandler.openURLWithOptionsOptionsParam = nil | ||
| } | ||
|
|
||
| // MARK: - handleUserActivity Tests | ||
|
|
||
| func test_handleUserActivity_invokesAppNotificationHandler() { | ||
| // Act | ||
| mparticle.handleUserActivity(testUserActivity) | ||
|
|
||
| // Assert - handleUserActivity directly calls the app notification handler | ||
| XCTAssertTrue(appNotificationHandler.continueUserActivityCalled) | ||
| XCTAssertEqual(appNotificationHandler.continueUserActivityUserActivityParam, testUserActivity) | ||
| XCTAssertNotNil(appNotificationHandler.continueUserActivityRestorationHandlerParam) | ||
| } | ||
|
|
||
| func test_handleUserActivity_withWebBrowsingActivity() { | ||
| // Arrange | ||
| let webActivity = NSUserActivity(activityType: NSUserActivityTypeBrowsingWeb) | ||
| webActivity.title = "Web Page" | ||
| webActivity.webpageURL = URL(string: "https://example.com/page") | ||
|
|
||
| // Act | ||
| mparticle.handleUserActivity(webActivity) | ||
|
|
||
| // Assert - Direct call to app notification handler | ||
| XCTAssertTrue(appNotificationHandler.continueUserActivityCalled) | ||
| XCTAssertEqual(appNotificationHandler.continueUserActivityUserActivityParam, webActivity) | ||
| } | ||
|
|
||
| func test_handleUserActivity_restorationHandlerIsEmpty() { | ||
| // Act | ||
| mparticle.handleUserActivity(testUserActivity) | ||
|
|
||
| // Assert | ||
| XCTAssertTrue(appNotificationHandler.continueUserActivityCalled) | ||
|
|
||
| // Verify the restoration handler is provided and safe to call | ||
| let restorationHandler = appNotificationHandler.continueUserActivityRestorationHandlerParam | ||
| XCTAssertNotNil(restorationHandler) | ||
|
|
||
| // Test that calling the restoration handler doesn't crash | ||
| XCTAssertNoThrow(restorationHandler?(nil)) | ||
| XCTAssertNoThrow(restorationHandler?([])) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,7 +23,11 @@ - (instancetype)initWithDictionary:(NSDictionary *)configurationDictionary { | |
| return nil; | ||
| } | ||
|
|
||
| NSData *ekConfigData = [NSJSONSerialization dataWithJSONObject:configurationDictionary options:0 error:nil]; | ||
| NSJSONWritingOptions options = 0; | ||
| if (@available(iOS 11.0, tvOS 11.0, *)) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why we need this check? Our min iOS version is 15.6
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current minimum deployment target is 9.0 though I do plan on upping that in future PRs/tickets. Would you like me to bring that into this ticket? @denischilik |
||
| options = NSJSONWritingSortedKeys; | ||
| } | ||
| NSData *ekConfigData = [NSJSONSerialization dataWithJSONObject:configurationDictionary options:options error:nil]; | ||
| NSString *ekConfigString = [[NSString alloc] initWithData:ekConfigData encoding:NSUTF8StringEncoding]; | ||
| _configurationHash = @([[MPIHasher hashString:ekConfigString] intValue]); | ||
|
|
||
|
|
@@ -114,16 +118,11 @@ - (id)initWithCoder:(NSCoder *)coder { | |
| @try { | ||
| configurationDictionary = [coder decodeObjectOfClass:[NSDictionary class] forKey:@"configurationDictionary"]; | ||
| } | ||
|
|
||
| @catch ( NSException *e) { | ||
| configurationDictionary = nil; | ||
| MPILogError(@"Exception decoding MPKitConfiguration Attributes: %@", [e reason]); | ||
| } | ||
|
|
||
| @finally { | ||
| self = [self initWithDictionary:configurationDictionary]; | ||
| } | ||
|
|
||
| self = [self initWithDictionary:configurationDictionary]; | ||
| if (!self) { | ||
| return nil; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -697,6 +697,46 @@ - (BOOL)continueUserActivity:(nonnull NSUserActivity *)userActivity restorationH | |
| return [self.appNotificationHandler continueUserActivity:userActivity restorationHandler:restorationHandler]; | ||
| } | ||
|
|
||
| - (void)handleURLContext:(UIOpenURLContext *)urlContext API_AVAILABLE(ios(13.0)){ | ||
| NSString *messageURL = [NSString stringWithFormat:@"Opening URLContext URL: %@", urlContext.URL]; | ||
| [logger debug:messageURL]; | ||
| NSString *messageSource = [NSString stringWithFormat:@"Source: %@", urlContext.options.sourceApplication ? urlContext.options.sourceApplication : @"unknown"]; | ||
| [logger debug:messageSource]; | ||
| NSString *messageAnnotation = [NSString stringWithFormat:@"Annotation: %@", urlContext.options.annotation]; | ||
| [logger debug:messageAnnotation]; | ||
| #if TARGET_OS_IOS == 1 | ||
| if (@available(iOS 14.5, *)) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like we also don't need this check |
||
| NSString *messageEventAttribution = [NSString stringWithFormat:@"Event Attribution: %@", urlContext.options.eventAttribution]; | ||
| [logger debug:messageEventAttribution]; | ||
| } | ||
| #endif | ||
| NSString *messageOpenInPlace = [NSString stringWithFormat:@"Open in place: %@", urlContext.options.openInPlace ? @"True" : @"False"]; | ||
| [logger debug:messageOpenInPlace]; | ||
|
|
||
| // Currently only one kit integration uses this dictionary for this key | ||
| // https://github.com/mparticle-integrations/mparticle-apple-integration-flurry/blob/a0856e271aa9a63a6668805582395dea63f96af5/mParticle-Flurry/MPKitFlurry.m#L148C38-L148C85 | ||
| NSDictionary *options = @{@"UIApplicationOpenURLOptionsSourceApplicationKey": urlContext.options.sourceApplication}; | ||
|
|
||
| [self.appNotificationHandler openURL:urlContext.URL options:options]; | ||
| } | ||
|
|
||
| - (void)handleUserActivity:(NSUserActivity *)userActivity { | ||
| NSString *message = [NSString stringWithFormat:@"User Activity Received"]; | ||
| [logger debug:message]; | ||
| NSString *messageType = [NSString stringWithFormat:@"User Activity Type: %@", userActivity.activityType]; | ||
| [logger debug:messageType]; | ||
| NSString *messageTitle = [NSString stringWithFormat:@"User Activity Title: %@", userActivity.title]; | ||
| [logger debug:messageTitle]; | ||
| NSString *messageUserInfo = [NSString stringWithFormat:@"User Activity User Info: %@", userActivity.userInfo]; | ||
| [logger debug:messageUserInfo]; | ||
| if (userActivity.activityType == NSUserActivityTypeBrowsingWeb) { | ||
| NSString *messageURL = [NSString stringWithFormat:@"Opening UserActivity URL: %@", userActivity.webpageURL]; | ||
| [logger debug:messageURL]; | ||
| } | ||
| // When provided by the SceneDelegate NSUserActivity is not paired with a restorationHandler | ||
| [self.appNotificationHandler continueUserActivity: userActivity restorationHandler:^(NSArray<id<UIUserActivityRestoring>> * _Nullable restorableObjects) {}]; | ||
| } | ||
|
|
||
| - (void)reset:(void (^)(void))completion { | ||
| [executor executeOnMessage:^{ | ||
| [self.kitContainer flushSerializedKits]; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.