Skip to content

Commit c02a7ab

Browse files
HarshRaghavWingifyParvesh Chauhan
authored and
Parvesh Chauhan
committed
Pull request #10: Feature/data360
Merge in SST/mobile-testing-ios-sdk from feature/data360 to dev * commit 'c7614e13009141cab522ba144eaca6ba1382e2e5': (9 commits) Fix - Track goal missing on Same Event Name ...
2 parents 4760159 + c7614e1 commit c02a7ab

14 files changed

+456
-46
lines changed

Demo/VWO Demo/VWOManager.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class VWOManager {
2222
VWO.logLevel = .debug
2323
let config = VWOConfig()
2424
// config.setCustomDimension(customDimensionKey: "userId", customDimensionValue: "userName")
25-
config.userID = "9c3832ad-15f9-420a-93cd-a7f2cde0f7bc"
25+
// config.userID = "9c3832ad-15f9-420a-93cd-a7f2cde0f7bc"
2626
// config.isChinaCDN = false
2727
VWO.launch(apiKey: apiKey, config: config, completion: {
2828
DispatchQueue.main.async {

VWO/Extensions/NSURLSession+Synchronous.m

+21
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,34 @@
77
//
88

99
#import "NSURLSession+Synchronous.h"
10+
#import "VWOUserDefaults.h"
11+
#import "VWOConstants.h"
1012

1113
// https://github.com/floschliep/NSURLSession-SynchronousTask
1214
@implementation NSURLSession (Synchronous)
1315

1416
- (nullable NSData *)sendSynchronousDataTaskWithURL:(nonnull NSURL *)url
1517
returningResponse:(NSURLResponse *_Nullable*_Nullable)response
1618
error:(NSError *_Nullable*_Nullable)error {
19+
if(VWOUserDefaults.IsEventArchEnabled != NULL && [VWOUserDefaults.IsEventArchEnabled isEqual:EventArchEnabled]){
20+
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
21+
[urlRequest setHTTPMethod:@"POST"];
22+
[urlRequest setValue:UserAgentValue forHTTPHeaderField:@"User-Agent"];
23+
24+
if(VWOUserDefaults.EventArchData != NULL){
25+
NSString *urlString = [url absoluteString];
26+
NSMutableDictionary *eventArchData = VWOUserDefaults.EventArchData;
27+
NSDictionary *payloadEventArch = [eventArchData objectForKey:urlString];
28+
29+
if(payloadEventArch != NULL){
30+
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payloadEventArch options:NSJSONWritingPrettyPrinted error:nil];
31+
[urlRequest setHTTPBody:jsonData];
32+
[VWOUserDefaults removeEventArchDataItem:urlString];
33+
}
34+
}
35+
36+
return [self sendSynchronousDataTaskWithRequest:urlRequest returningResponse:response error:error];
37+
}
1738
return [self sendSynchronousDataTaskWithRequest:[NSURLRequest requestWithURL:url] returningResponse:response error:error];
1839
}
1940

VWO/Models/VWOCampaign.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ typedef NS_ENUM(NSInteger, CampaignStatus) {
3636
-(nullable instancetype)setGroups:(NSDictionary *) campaignDict;
3737
- (nullable id)variationForKey:(NSString *)key;
3838
- (nullable id)testKey:(NSString *)testKey;
39-
- (nullable VWOGoal *)goalForIdentifier:(NSString *)identifier;
39+
- (nullable NSMutableArray <VWOGoal *>*)goalForIdentifier:(NSString *)identifier;
4040

4141
@end
4242

VWO/Models/VWOCampaign.m

+4-3
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,15 @@ - (nullable id)variationForKey:(NSString *)key {
120120
return self.variation.changes[key];
121121
}
122122

123-
- (nullable VWOGoal *)goalForIdentifier:(NSString *)identifier {
123+
- (nullable NSMutableArray <VWOGoal *>*)goalForIdentifier:(NSString *)identifier {
124124
NSParameterAssert(identifier);
125+
NSMutableArray <VWOGoal *>*matchedGoalsArray = [NSMutableArray new];
125126
for (VWOGoal *goal in self.goals) {
126127
if ([goal.identifier isEqualToString:identifier]) {
127-
return goal;
128+
[matchedGoalsArray addObject:goal];
128129
}
129130
}
130-
return nil;
131+
return matchedGoalsArray;
131132
}
132133

133134
-(nullable VWOGroup *)groupForMeg{

VWO/Models/VWOGoal.h

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ typedef NS_ENUM(NSInteger, GoalType) {
2020
@property(nonatomic, assign) int iD;
2121
@property NSString *identifier;
2222
@property (nonatomic, assign) GoalType type;
23+
@property NSString *revenueProp;
24+
@property(nonatomic, assign) int mca;
2325

2426
- (nullable instancetype)initWithDictionary:(NSDictionary *)goalDict;
2527

VWO/Models/VWOGoal.m

+21-10
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,24 @@
99
#import "VWOGoal.h"
1010
#import "NSDictionary+VWO.h"
1111
#import "VWOLogger.h"
12+
#import "VWOConstants.h"
1213

13-
static NSString * kId = @"id";
14-
static NSString * kType = @"type";
15-
static NSString * kIdentifier = @"identifier";
16-
14+
static NSString * kId = @"id";
15+
static NSString * kType = @"type";
16+
static NSString * kIdentifier = @"identifier";
17+
static NSString * kRevenueProp = @"revenueProp";
18+
static NSString * kMca = @"mca";
1719
@implementation VWOGoal
1820

19-
- (instancetype)initWithId:(int)iD identifier:(NSString *)identifier type:(GoalType)type {
21+
- (instancetype)initWithId:(int)iD identifier:(NSString *)identifier type:(GoalType)type revenueProp:(NSString *)revenueProp mca:(int)mca{
2022
NSParameterAssert(identifier);
2123
self = [super init];
2224
if (self) {
23-
self.iD = iD;
24-
self.identifier = identifier;
25-
self.type = type;
25+
self.iD = iD;
26+
self.identifier = identifier;
27+
self.type = type;
28+
self.revenueProp = revenueProp;
29+
self.mca = mca;
2630
}
2731
return self;
2832
}
@@ -40,9 +44,16 @@ - (instancetype)initWithDictionary:(NSDictionary *)goalDict {
4044
NSString *identifier = goalDict[kIdentifier];
4145

4246
GoalType type = GoalTypeCustom;
43-
if([goalDict[kType] isEqualToString:@"REVENUE_TRACKING"]) { type = GoalTypeRevenue; }
47+
NSString *revenueProp = @"";
48+
49+
NSString *nonConstRevenueTracking = [ConstRevenueTracking copy];
50+
if([goalDict[kType] isEqualToString:nonConstRevenueTracking]) {
51+
type = GoalTypeRevenue;
52+
revenueProp = goalDict[kRevenueProp];
53+
}
4454

45-
return [self initWithId:id identifier:identifier type:type];
55+
int mca = [goalDict[kMca] intValue];
56+
return [self initWithId:id identifier:identifier type:type revenueProp:revenueProp mca:mca];
4657
}
4758

4859
- (NSString *)description {

VWO/VWOCampaignFetcher.m

+13-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ + (nullable VWOCampaignArray *)getCampaignsWithTimeout:(NSNumber *)timeout
6565
//handle NSDict nd NSArray comparison
6666
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonerror];
6767
VWOLogDebug(@"%@", jsonDict);
68-
68+
69+
[self checkForIsEventArchEnabledFlag:jsonDict];
6970
VWOCampaignArray *allCampaigns = [self EUCheckAndDataFetching:jsonDict];
7071

7172
if (completionBlock) {
@@ -139,4 +140,15 @@ + (VWOCampaignArray *)EUCheckAndDataFetching:(NSDictionary *) jsonDict{
139140
return newCampaignList;
140141
}
141142

143+
+(void)checkForIsEventArchEnabledFlag:(NSDictionary *)jsonDict{
144+
BOOL isEventArchEnabledFlag = [[jsonDict objectForKey:ConstIsEventArchEnabled] boolValue];
145+
// BOOL *isEventArchEnabledFlag = [jsonDict objectForKey: ConstIsEventArchEnabled];
146+
if(isEventArchEnabledFlag != NULL && isEventArchEnabledFlag == YES){
147+
[VWOUserDefaults updateIsEventArchEnabled: EventArchEnabled];
148+
}
149+
else{
150+
[VWOUserDefaults updateIsEventArchEnabled: EventArchDisabled];
151+
}
152+
}
153+
142154
@end

VWO/VWOConstants.h

+42
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,48 @@ extern NSString const *ConstCampaignGroups;
1414
extern NSString const *ConstType;
1515
extern NSString const *ConstCampaigns;
1616
extern NSString const *ConstCollectionPrefix;
17+
extern NSString const *ConstIsEventArchEnabled;
1718
extern NSString const *ConstAPIVersion;
19+
extern NSString const *ConstRevenueTracking;
1820

1921
@end
22+
23+
@interface VWOData360Constants : NSObject
24+
25+
extern NSString const *ConstGroups;
26+
27+
extern NSString const *UserAgentValue;
28+
extern NSString const *EventArchEnabled;
29+
extern NSString const *EventArchDisabled;
30+
31+
// MARK: - QueryParamsEventArchEnabled
32+
extern NSString const *APIEventName;
33+
extern NSString const *TrackUserEventName;
34+
extern NSString const *PushEventName;
35+
extern NSString const *AccountID;
36+
extern NSString const *APIKey;
37+
extern NSString const *CurrentTimeInMillis;
38+
extern NSString const *Random;
39+
40+
// MARK: - Data360PayloadParams
41+
extern NSString const *D;
42+
extern NSString const *MessageID;// uuid-currentTimeStamp in seconds
43+
extern NSString const *VisitorID;//uuid
44+
extern NSString const *SessionID;//current timestamp in seconds
45+
extern NSString const *Event;
46+
extern NSString const *EventProps;
47+
extern NSString const *SDKName;//name of the sdk
48+
extern NSString const *SDKNameValue;
49+
extern NSString const *SDKVersion;//version of the sdk
50+
extern NSString const *CampaignID;//id of the campaign
51+
extern NSString const *VariationID;//id of the variation
52+
extern NSString const *IsFirst;//this will be sent as 1 always
53+
extern NSString const *IsCustomEvent;//this will always be sent as true
54+
extern NSString const *VWOMeta;
55+
extern NSString const *Metric;
56+
extern NSString const *InternalVisitor;
57+
extern NSString const *ExternalVisitor;
58+
extern NSString const *VisitorProps;
59+
extern NSString const *Data360EventName;//event name
60+
extern NSString const *EventTime;//current timestamp in milliseconds
61+
@end

VWO/VWOConstants.m

+46
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,53 @@ @implementation VWOConstants: NSObject
2020

2121
NSString const *ConstCollectionPrefix = @"collectionPrefix";
2222

23+
NSString const *ConstIsEventArchEnabled = @"isEventArchEnabled";
24+
25+
NSString const *ConstRevenueTracking = @"REVENUE_TRACKING";
26+
2327
//for making API calls
2428
NSString const *ConstAPIVersion = @"3";
2529

2630
@end
31+
32+
@implementation VWOData360Constants: NSObject
33+
34+
//for enabling EventArch
35+
NSString const *EventArchEnabled = @"eventArchEnabled";
36+
37+
//for disabling EventArch
38+
NSString const *EventArchDisabled = @"eventArchDisabled";
39+
40+
NSString const *UserAgentValue = @"iOSVwoAb";
41+
42+
//query params
43+
NSString const *APIEventName = @"en";// value changes based on the current API call
44+
NSString const *TrackUserEventName = @"vwo_variationShown";
45+
NSString const *PushEventName = @"vwo_syncVisitorProp";
46+
NSString const *AccountID = @"a";
47+
NSString const *APIKey = @"env";
48+
NSString const *CurrentTimeInMillis = @"eTime";
49+
NSString const *Random = @"random";
50+
51+
//payloads params
52+
NSString const *D = @"d";
53+
NSString const *MessageID = @"msgId";// uuid-currentTimeStamp in seconds
54+
NSString const *VisitorID = @"visId";//uuid
55+
NSString const *SessionID = @"sessionId";//current timestamp in seconds
56+
NSString const *Event = @"event";
57+
NSString const *EventProps = @"props";
58+
NSString const *SDKName = @"sdkName";//name of the sdk
59+
NSString const *SDKNameValue = @"vwo-ios-sdk";
60+
NSString const *SDKVersion = @"sdkVersion";//version of the sdk
61+
NSString const *CampaignID = @"id";//id of the campaign
62+
NSString const *VariationID = @"variation";//id of the variation
63+
NSString const *IsFirst = @"isFirst";//this will be sent as 1 always
64+
NSString const *IsCustomEvent = @"isCustomEvent";//this will always be sent as true
65+
NSString const *VWOMeta = @"vwoMeta";
66+
NSString const *Metric = @"metric";
67+
NSString const *InternalVisitor = @"$visitor";
68+
NSString const *ExternalVisitor = @"visitor";
69+
NSString const *VisitorProps = @"props";
70+
NSString const *Data360EventName = @"name";//event name
71+
NSString const *EventTime = @"time";//current timestamp in milliseconds
72+
@end

VWO/VWOController.m

+74-20
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#import "VWOSocketConnector.h"
1111
#import "VWOLogger.h"
1212
#import "VWOCampaign.h"
13+
#import "VWOConstants.h"
1314
#import "VWOURLQueue.h"
1415
#import "VWOFile.h"
1516
#import "VWOURL.h"
@@ -203,30 +204,62 @@ - (void)trackConversion:(NSString *)goalIdentifier withValue:(NSNumber *)value {
203204

204205
//Check if the goal is already marked.
205206
for (VWOCampaign *campaign in _campaignList) {
206-
VWOGoal *matchedGoal = [campaign goalForIdentifier:goalIdentifier];
207-
if (matchedGoal) {
208-
209-
if ([VWOUserDefaults isGoalMarked:matchedGoal inCampaign:campaign]) {
210-
VWOLogDebug(@"Goal '%@' already marked. Will not be marked again", matchedGoal);
211-
return;
207+
NSMutableArray <VWOGoal *>*matchedGoals = [campaign goalForIdentifier:goalIdentifier];
208+
if([matchedGoals count] == 0){
209+
continue;
210+
}
211+
212+
for(VWOGoal *matchedGoal in matchedGoals){
213+
if (matchedGoal) {
214+
215+
if ([VWOUserDefaults isGoalMarked:matchedGoal inCampaign:campaign]) {
216+
BOOL isEventArchEnabled = [VWOUserDefaults IsEventArchEnabled];
217+
if(!isEventArchEnabled){
218+
VWOLogDebug(@"Goal '%@' already marked and eventArch is not enabled. Will not be marked again", matchedGoal);
219+
return;
220+
}
221+
if([matchedGoal mca] != -1){
222+
//if mca flag != -1, then goal is not triggered multiple times.
223+
VWOLogDebug(@"Goal '%@' already marked. Will not be marked again", matchedGoal);
224+
return;
225+
}
226+
}
212227
}
213228
}
214229
}
215230

216231
// Mark goal(Goal can be present in multiple campaigns
217232
for (VWOCampaign *campaign in _campaignList) {
218-
VWOGoal *matchedGoal = [campaign goalForIdentifier:goalIdentifier];
219-
if (matchedGoal) {
220-
if ([VWOUserDefaults isTrackingUserForCampaign:campaign]) {
221-
[VWOUserDefaults markGoalConversion:matchedGoal inCampaign:campaign];
222-
NSURL *url = [_vwoURL forMarkingGoal:matchedGoal
223-
withValue:value
224-
campaign:campaign
225-
dateTime:NSDate.date];
226-
NSString *description = [NSString stringWithFormat:@"Goal %@", matchedGoal];
227-
[pendingURLQueue enqueue:url maxRetry:10 description:description];
228-
} else {
229-
VWOLogWarning(@"Goal %@ not tracked for %@ as user is not tracked", matchedGoal, campaign);
233+
NSMutableArray <VWOGoal *>*matchedGoals = [campaign goalForIdentifier:goalIdentifier];
234+
if([matchedGoals count] == 0){
235+
continue;
236+
}
237+
for(VWOGoal *matchedGoal in matchedGoals){
238+
if (matchedGoal) {
239+
if ([VWOUserDefaults isTrackingUserForCampaign:campaign]) {
240+
[VWOUserDefaults markGoalConversion:matchedGoal inCampaign:campaign];
241+
242+
NSURL *url = NULL;
243+
if((VWOUserDefaults.IsEventArchEnabled != NULL) &&
244+
([VWOUserDefaults.IsEventArchEnabled isEqualToString:EventArchEnabled])){
245+
//for Event based API calls
246+
url = [_vwoURL forMarkingGoalEventArch:matchedGoal
247+
withValue:value
248+
campaign:campaign
249+
dateTime:NSDate.date];
250+
}else{
251+
//for previous version support
252+
url = [_vwoURL forMarkingGoal:matchedGoal
253+
withValue:value
254+
campaign:campaign
255+
dateTime:NSDate.date];
256+
}
257+
258+
NSString *description = [NSString stringWithFormat:@"Goal %@", matchedGoal];
259+
[pendingURLQueue enqueue:url maxRetry:10 description:description];
260+
} else {
261+
VWOLogWarning(@"Goal %@ not tracked for %@ as user is not tracked", matchedGoal, campaign);
262+
}
230263
}
231264
}
232265
}
@@ -400,7 +433,17 @@ - (void)trackUserForCampaign:(VWOCampaign *)campaign {
400433

401434
//Send network request and notification only if the campaign is running
402435

403-
NSURL *url = [_vwoURL forMakingUserPartOfCampaign:campaign dateTime:NSDate.date config: _vwoConfig];
436+
NSURL *url = NULL;
437+
438+
if((VWOUserDefaults.IsEventArchEnabled != NULL) &&
439+
([VWOUserDefaults.IsEventArchEnabled isEqualToString:EventArchEnabled])){
440+
//for Event based API calls
441+
url = [_vwoURL forMakingUserPartOfCampaignEventArch:campaign dateTime:NSDate.date config: _vwoConfig];
442+
}else{
443+
//for previous version support
444+
url = [_vwoURL forMakingUserPartOfCampaign:campaign dateTime:NSDate.date config: _vwoConfig];
445+
}
446+
404447
NSString *description = [NSString stringWithFormat:@"Track user %@ %@", campaign, campaign.variation];
405448
[pendingURLQueue enqueue:url maxRetry:10 description:description];
406449

@@ -416,7 +459,18 @@ - (void)pushCustomDimension:(nonnull NSString *)customDimensionKey withCustomDim
416459
return;
417460
}
418461

419-
NSURL *url = [_vwoURL forPushingCustomDimension:customDimensionKey withCustomDimensionValue:customDimensionValue dateTime:NSDate.date];
462+
463+
NSURL *url = NULL;
464+
465+
if((VWOUserDefaults.IsEventArchEnabled != NULL) &&
466+
([VWOUserDefaults.IsEventArchEnabled isEqualToString:EventArchEnabled])){
467+
//for Event based API calls
468+
url = [_vwoURL forPushingCustomDimensionEventArch:customDimensionKey withCustomDimensionValue:customDimensionValue dateTime:NSDate.date];
469+
}else{
470+
//for previous version support
471+
url = [_vwoURL forPushingCustomDimension:customDimensionKey withCustomDimensionValue:customDimensionValue dateTime:NSDate.date];
472+
}
473+
420474
NSString *description = [NSString stringWithFormat:@"Custom Dimension %@ %@", customDimensionKey, customDimensionValue];
421475
[pendingURLQueue enqueue:url maxRetry:10 description:description];
422476

0 commit comments

Comments
 (0)