Skip to content
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

fix: Properly attribute events when workspace switches on new launch #288

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mParticle-Apple-SDK/Data Model/MPUpload.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#import "MPEnums.h"

@class MPSession;
@class MPNetworkOptions;

// Upload credentials and options
@interface MPUploadSettings : NSObject <NSCopying, NSSecureCoding>
Expand All @@ -20,6 +21,8 @@

- (nonnull instancetype)initWithApiKey:(nonnull NSString *)apiKey secret:(nonnull NSString *)secret eventsHost:(nullable NSString *)eventsHost eventsTrackingHost:(nullable NSString *)eventsTrackingHost overridesEventsSubdirectory:(BOOL)overridesEventsSubdirectory aliasHost:(nullable NSString *)aliasHost aliasTrackingHost:(nullable NSString *)aliasTrackingHost overridesAliasSubdirectory:(BOOL)overridesAliasSubdirectory eventsOnly:(BOOL)eventsOnly;

- (nonnull instancetype)initWithApiKey:(nonnull NSString *)apiKey secret:(nonnull NSString *)secret networkOptions:(nullable MPNetworkOptions *)networkOptions;

@end

@interface MPUpload : MPDataModelAbstract <NSCopying, MPDataModelProtocol>
Expand Down
20 changes: 13 additions & 7 deletions mParticle-Apple-SDK/Data Model/MPUpload.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@ + (MPUploadSettings *)currentUploadSettings {
MParticle *mParticle = [MParticle sharedInstance];
MPUploadSettings *uploadSettings = [[MPUploadSettings alloc] initWithApiKey:mParticle.stateMachine.apiKey
secret:mParticle.stateMachine.secret
eventsHost:mParticle.networkOptions.eventsHost
eventsTrackingHost:mParticle.networkOptions.eventsTrackingHost
overridesEventsSubdirectory:mParticle.networkOptions.overridesEventsSubdirectory
aliasHost:mParticle.networkOptions.aliasHost
aliasTrackingHost:mParticle.networkOptions.aliasTrackingHost
overridesAliasSubdirectory:mParticle.networkOptions.overridesAliasSubdirectory
eventsOnly:mParticle.networkOptions.eventsOnly];
networkOptions:mParticle.networkOptions];
return uploadSettings;
}

Expand All @@ -39,6 +33,18 @@ - (instancetype)initWithApiKey:(nonnull NSString *)apiKey secret:(nonnull NSStri
return self;
}

- (nonnull instancetype)initWithApiKey:(nonnull NSString *)apiKey secret:(nonnull NSString *)secret networkOptions:(MPNetworkOptions *)networkOptions {
return [self initWithApiKey:apiKey
secret:secret
eventsHost:networkOptions.eventsHost
eventsTrackingHost:networkOptions.eventsTrackingHost
overridesEventsSubdirectory:networkOptions.overridesEventsSubdirectory
aliasHost:networkOptions.aliasHost
aliasTrackingHost:networkOptions.aliasTrackingHost
overridesAliasSubdirectory:networkOptions.overridesAliasSubdirectory
eventsOnly:networkOptions.eventsOnly];
}

static NSString * const kApiKey = @"apiKey";
static NSString * const kSecret = @"secret";
static NSString * const kEventsHost = @"eventsHost";
Expand Down
4 changes: 2 additions & 2 deletions mParticle-Apple-SDK/Include/mParticle.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ Defaults to false. Prevents the eventsHost above from overwriting the alias endp

(Provided to accomodate certain advanced use cases. Most integrations of the SDK will not require modifying this property.)
*/
@property (nonatomic, strong, readwrite) MPNetworkOptions *networkOptions;
@property (nonatomic, strong, readwrite, nullable) MPNetworkOptions *networkOptions;

/**
Consent state.
Expand Down Expand Up @@ -572,7 +572,7 @@ Defaults to false. Prevents the eventsHost above from overwriting the alias endp
Allows you to proxy SDK traffic by overriding the default network endpoints and certificates used by the SDK.
@see MParticleOptions
*/
@property (nonatomic, readonly) MPNetworkOptions *networkOptions;
@property (nonatomic, readonly, nullable) MPNetworkOptions *networkOptions;

#if TARGET_OS_IOS == 1
/**
Expand Down
6 changes: 4 additions & 2 deletions mParticle-Apple-SDK/MPBackendController.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
@class MPCommerceEvent;
@class MPConsentState;
@class MParticleSession;
@class MPUploadSettings;
@class MPNetworkOptions;

@protocol MPBackendControllerDelegate;

Expand Down Expand Up @@ -97,14 +99,14 @@ extern const NSInteger kInvalidKey;
- (void)setUserAttribute:(nonnull NSString *)key values:(nullable NSArray<NSString *> *)values timestamp:(nonnull NSDate *)timestamp completionHandler:(void (^ _Nullable)(NSString * _Nonnull key, NSArray<NSString *> * _Nullable values, MPExecStatus execStatus))completionHandler;
- (void)removeUserAttribute:(nonnull NSString *)key timestamp:(nonnull NSDate *)timestamp completionHandler:(void (^ _Nullable)(NSString * _Nullable key, id _Nullable value, MPExecStatus execStatus))completionHandler;
- (void)setUserIdentity:(nullable NSString *)identityString identityType:(MPUserIdentity)identityType timestamp:(nonnull NSDate *)timestamp completionHandler:(void (^ _Nonnull)(NSString * _Nullable identityString, MPUserIdentity identityType, MPExecStatus execStatus))completionHandler;
- (void)startWithKey:(nonnull NSString *)apiKey secret:(nonnull NSString *)secret firstRun:(BOOL)firstRun installationType:(MPInstallationType)installationType proxyAppDelegate:(BOOL)proxyAppDelegate startKitsAsync:(BOOL)startKitsAsync consentState:(MPConsentState *_Nullable)consentState completionHandler:(dispatch_block_t _Nonnull)completionHandler;
- (void)startWithKey:(nonnull NSString *)apiKey secret:(nonnull NSString *)secret networkOptions:(nullable MPNetworkOptions *)networkOptions firstRun:(BOOL)firstRun installationType:(MPInstallationType)installationType proxyAppDelegate:(BOOL)proxyAppDelegate startKitsAsync:(BOOL)startKitsAsync consentState:(MPConsentState *_Nullable)consentState completionHandler:(dispatch_block_t _Nonnull)completionHandler;
- (void)unproxyOriginalAppDelegate;
- (void)saveMessage:(nonnull MPMessage *)message updateSession:(BOOL)updateSession;
- (void)skipNextUpload;
- (MPExecStatus)waitForKitsAndUploadWithCompletionHandler:(void (^ _Nullable)(void))completionHandler;
- (nonnull NSMutableDictionary<NSString *, id> *)userAttributesForUserId:(nonnull NSNumber *)userId;
- (nonnull NSMutableArray<NSDictionary<NSString *, id> *> *)userIdentitiesForUserId:(nonnull NSNumber *)userId;
- (void)prepareBatchesForUpload;
- (void)prepareBatchesForUpload:(nonnull MPUploadSettings *)uploadSettings;

#if TARGET_OS_IOS == 1
#ifndef MPARTICLE_LOCATION_DISABLE
Expand Down
22 changes: 18 additions & 4 deletions mParticle-Apple-SDK/MPBackendController.m
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ - (void)skipNextUpload {
skipNextUpload = YES;
}

- (void)prepareBatchesForUpload {
- (void)prepareBatchesForUpload:(MPUploadSettings *)uploadSettings {
MPPersistenceController *persistence = [MParticle sharedInstance].persistenceController;

//Fetch all stored messages (1)
Expand All @@ -687,7 +687,7 @@ - (void)prepareBatchesForUpload {
uploadInterval:self.uploadInterval
dataPlanId:nullableDataPlanId
dataPlanVersion:nullableDataPlanVersion
uploadSettings:[MPUploadSettings currentUploadSettings]];
uploadSettings:uploadSettings];
[uploadBuilder withUserAttributes:[self userAttributesForUserId:mpid] deletedUserAttributes:self.deletedUserAttributes];
[uploadBuilder withUserIdentities:[self userIdentitiesForUserId:mpid]];
[uploadBuilder build:^(MPUpload *upload) {
Expand All @@ -712,7 +712,7 @@ - (void)prepareBatchesForUpload {

- (void)uploadBatchesWithCompletionHandler:(void(^)(BOOL success))completionHandler {
// Prepare upload records
[self prepareBatchesForUpload];
[self prepareBatchesForUpload:[MPUploadSettings currentUploadSettings]];

const void (^completionHandlerCopy)(BOOL) = [completionHandler copy];
MPPersistenceController *persistence = [MParticle sharedInstance].persistenceController;
Expand Down Expand Up @@ -1500,7 +1500,7 @@ - (MPExecStatus)setSessionAttribute:(MPSession *)session key:(NSString *)key val
return MPExecStatusSuccess;
}

- (void)startWithKey:(NSString *)apiKey secret:(NSString *)secret firstRun:(BOOL)firstRun installationType:(MPInstallationType)installationType proxyAppDelegate:(BOOL)proxyAppDelegate startKitsAsync:(BOOL)startKitsAsync consentState:(MPConsentState *)consentState completionHandler:(dispatch_block_t)completionHandler {
- (void)startWithKey:(NSString *)apiKey secret:(NSString *)secret networkOptions:(nullable MPNetworkOptions *)networkOptions firstRun:(BOOL)firstRun installationType:(MPInstallationType)installationType proxyAppDelegate:(BOOL)proxyAppDelegate startKitsAsync:(BOOL)startKitsAsync consentState:(MPConsentState *)consentState completionHandler:(dispatch_block_t)completionHandler {
[MPListenerController.sharedInstance onAPICalled:_cmd parameter1:apiKey parameter2:secret parameter3:@(firstRun) parameter4:consentState];

if (![MPStateMachine isAppExtension]) {
Expand Down Expand Up @@ -1536,6 +1536,20 @@ - (void)startWithKey:(NSString *)apiKey secret:(NSString *)secret firstRun:(BOOL
dispatch_async([MParticle messageQueue], ^{
[MParticle sharedInstance].persistenceController = [[MPPersistenceController alloc] init];

// Check if we've switched workspaces on startup
MPUploadSettings *lastUploadSettings = [[MPIUserDefaults standardUserDefaults] lastUploadSettings];
if (![lastUploadSettings.apiKey isEqualToString:apiKey]) {
// Different workspace, so batch previous messages under old upload settings before starting
[self prepareBatchesForUpload:lastUploadSettings];

// Delete the cached config
[MPResponseConfig deleteConfig];
}

// Cache the upload settings in case we switch workspaces on startup
MPUploadSettings *uploadSettings = [[MPUploadSettings alloc] initWithApiKey:apiKey secret:secret networkOptions:networkOptions];
[[MPIUserDefaults standardUserDefaults] setLastUploadSettings:uploadSettings];

// Restore cached config if exists
[MPResponseConfig restore];

Expand Down
1 change: 1 addition & 0 deletions mParticle-Apple-SDK/MPIConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ extern NSString * _Nonnull const kMPUserAgentValueUserDefaultsKey;
extern NSString * _Nonnull const kMPFirstSeenUser;
extern NSString * _Nonnull const kMPLastSeenUser;
extern NSString * _Nonnull const kMPAppForePreviousForegroundTime;
extern NSString * _Nonnull const kMPLastUploadSettingsUserDefaultsKey;

// Remote configuration
extern NSString * _Nonnull const kMPRemoteConfigExceptionHandlingModeKey;
Expand Down
1 change: 1 addition & 0 deletions mParticle-Apple-SDK/MPIConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@
NSString *const kMPFirstSeenUser = @"fsu";
NSString *const kMPLastSeenUser = @"lsu";
NSString *const kMPAppForePreviousForegroundTime = @"pft";
NSString *const kMPLastUploadSettingsUserDefaultsKey = @"lastUploadSettings";

// Remote configuration
NSString *const kMPRemoteConfigExceptionHandlingModeKey = @"cue";
Expand Down
3 changes: 3 additions & 0 deletions mParticle-Apple-SDK/Utils/MPIUserDefaults.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import <Foundation/Foundation.h>

@class MPKitConfiguration;
@class MPUploadSettings;

@interface MPIUserDefaults : NSObject

Expand Down Expand Up @@ -29,6 +30,8 @@
- (BOOL)isConfigurationParametersOutdated;
- (void)setSideloadedKitsCount:(NSUInteger)sideloadedKitsCount;
- (NSUInteger)sideloadedKitsCount;
- (void)setLastUploadSettings:(nullable MPUploadSettings *)lastUploadSettings;
- (nullable MPUploadSettings *)lastUploadSettings;

+ (NSString *_Nullable)stringFromDeviceToken:(NSData *_Nonnull)deviceToken;

Expand Down
30 changes: 30 additions & 0 deletions mParticle-Apple-SDK/Utils/MPIUserDefaults.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#import "MPStateMachine.h"
#import "MPKitContainer.h"
#import "MParticleSwift.h"
#import "MPUpload.h"

@interface MParticle ()

Expand Down Expand Up @@ -434,6 +435,35 @@ - (NSUInteger)sideloadedKitsCount {
return [[[NSUserDefaults standardUserDefaults] objectForKey:MPSideloadedKitsCountUserDefaultsKey] intValue];
}

- (void)setLastUploadSettings:(nullable MPUploadSettings *)lastUploadSettings {
if (!lastUploadSettings) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kMPLastUploadSettingsUserDefaultsKey];
return;
}

@try {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:lastUploadSettings];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:kMPLastUploadSettingsUserDefaultsKey];
} @catch(NSException *exception) {
MPILogError(@"Error serializing last upload settings: %@: %@", exception.name, exception.reason);
[self setLastUploadSettings:nil];
}
}

- (nullable MPUploadSettings *)lastUploadSettings {
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:kMPLastUploadSettingsUserDefaultsKey];
if (data) {
@try {
MPUploadSettings *uploadSettings = [NSKeyedUnarchiver unarchiveObjectWithData:data];
return uploadSettings;
} @catch(NSException *exception) {
MPILogError(@"Error deserializing last upload settings: %@: %@", exception.name, exception.reason);
[self setLastUploadSettings:nil];
}
}
return nil;
}

#pragma mark Objective-C Literals
- (id)objectForKeyedSubscript:(NSString *const)key {
if ([key isEqualToString:@"mpid"]) {
Expand Down
6 changes: 4 additions & 2 deletions mParticle-Apple-SDK/mParticle.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#import "MPDataPlanFilter.h"
#import "MPResponseConfig.h"
#import "MParticleSwift.h"
#import "MPUpload.h"

#if TARGET_OS_IOS == 1
#ifndef MPARTICLE_LOCATION_DISABLE
Expand Down Expand Up @@ -74,7 +75,7 @@ @interface MParticle() <MPBackendControllerDelegate
@property (nonatomic, strong, nullable) MPKitActivity *kitActivity;
@property (nonatomic) BOOL initialized;
@property (nonatomic, strong, nonnull) NSMutableArray *kitsInitializedBlocks;
@property (nonatomic, readwrite) MPNetworkOptions *networkOptions;
@property (nonatomic, readwrite, nullable) MPNetworkOptions *networkOptions;
@property (nonatomic, strong, nullable) NSArray<NSDictionary *> *deferredKitConfiguration;
@property (nonatomic, strong) MParticleWebView *webView;
@property (nonatomic, strong, nullable) NSString *dataPlanId;
Expand Down Expand Up @@ -613,6 +614,7 @@ - (void)startWithOptions:(MParticleOptions *)options {

[self.backendController startWithKey:apiKey
secret:secret
networkOptions:options.networkOptions
firstRun:firstRun
installationType:installationType
proxyAppDelegate:proxyAppDelegate
Expand Down Expand Up @@ -765,7 +767,7 @@ - (void)switchWorkspaceWithOptions:(MParticleOptions *)options {

// Batch any remaining messages into upload records
[MParticle executeOnMessage:^{
[self.backendController prepareBatchesForUpload];
[self.backendController prepareBatchesForUpload:[MPUploadSettings currentUploadSettings]];
finishReset();
}];
} else {
Expand Down
Loading