Skip to content

Commit

Permalink
Merge pull request #369 from CleverTap/develop
Browse files Browse the repository at this point in the history
Release v7.0.1
  • Loading branch information
kushCT authored Aug 22, 2024
2 parents 9db172c + 26c5601 commit 7c6ec5f
Show file tree
Hide file tree
Showing 15 changed files with 93 additions and 85 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Change Log
All notable changes to this project will be documented in this file.

### [Version 7.0.1](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/7.0.1) (August 22, 2024)

#### Fixed
- Fixes a bug where some user properties were being sent with an incorrect prefix

### [Version 7.0.0](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/7.0.0) (August 07, 2024)

#### Added
Expand Down
41 changes: 11 additions & 30 deletions CleverTapSDK/CTConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,40 +226,21 @@ extern NSString *CLTAP_PROFILE_IDENTITY_KEY;
#define CLTAP_INAPP_HTML_SPLIT @"\"##Vars##\""
#define CLTAP_INAPP_IMAGE_INTERSTITIAL_HTML_NAME @"image_interstitial"

#pragma mark Constants for persisting Facebook data
#define CLTAP_FB_NAME @"fbName"
#define CLTAP_FB_ID @"fbId"
#define CLTAP_FB_EMAIL @"fbEmail"
#define CLTAP_FB_GENDER @"fbGender"
#define CLTAP_FB_EDUCATION @"fbEducation"
#define CLTAP_FB_EMPLOYED @"fbEmployed"
#define CLTAP_FB_DOB @"fbDOB"
#define CLTAP_FB_MARRIED @"fbMarried"

#pragma mark Constants for persisting G+ data
#define CLTAP_GP_NAME @"gpName"
#define CLTAP_GP_ID @"gpId"
#define CLTAP_GP_EMAIL @"gpEmail"
#define CLTAP_GP_GENDER @"gpGender"
#define CLTAP_GP_EMPLOYED @"gpEmployed"
#define CLTAP_GP_DOB @"gpDOB"
#define CLTAP_GP_MARRIED @"gpMarried"

#pragma mark Constants for persisting system data
#define CLTAP_SYS_CARRIER @"sysCarrier"
#define CLTAP_SYS_CC @"sysCountryCode"
#define CLTAP_SYS_TZ @"sysTZ"

#define CLTAP_USER_NAME @"userName"
#define CLTAP_USER_EMAIL @"userEmail"
#define CLTAP_USER_EDUCATION @"userEducation"
#define CLTAP_USER_MARRIED @"userMarried"
#define CLTAP_USER_DOB @"userDOB"
#define CLTAP_USER_BIRTHDAY @"userBirthday"
#define CLTAP_USER_EMPLOYED @"userEmployed"
#define CLTAP_USER_GENDER @"userGender"
#define CLTAP_USER_PHONE @"userPhone"
#define CLTAP_USER_AGE @"userAge"
#define CLTAP_USER_NAME @"Name"
#define CLTAP_USER_EMAIL @"Email"
#define CLTAP_USER_EDUCATION @"Education"
#define CLTAP_USER_MARRIED @"Married"
#define CLTAP_USER_DOB @"DOB"
#define CLTAP_USER_BIRTHDAY @"Birthday"
#define CLTAP_USER_EMPLOYED @"Employed"
#define CLTAP_USER_GENDER @"Gender"
#define CLTAP_USER_PHONE @"Phone"
#define CLTAP_USER_AGE @"Age"

#define CLTAP_OPTOUT @"ct_optout"

Expand All @@ -283,4 +264,4 @@ extern NSString *CLTAP_PROFILE_IDENTITY_KEY;
#pragma mark Constants for Encryption
#define CLTAP_ENCRYPTION_LEVEL @"CleverTapEncryptionLevel"
#define CLTAP_ENCRYPTION_IV @"__CL3>3Rt#P__1V_"
#define CLTAP_ENCRYPTION_PII_DATA (@[@"Identity", @"userEmail", @"userPhone", @"userName"]);
#define CLTAP_ENCRYPTION_PII_DATA (@[@"Identity", @"Email", @"Phone", @"Name"]);
2 changes: 0 additions & 2 deletions CleverTapSDK/CTKnownProfileFields.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ typedef enum {

@interface CTKnownProfileFields : NSObject

+ (NSString *)getStorageValueForField:(KnownField)field;

+ (KnownField)getKnownFieldIfPossibleForKey:(NSString *)key;

@end
26 changes: 0 additions & 26 deletions CleverTapSDK/CTKnownProfileFields.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,6 @@
@implementation CTKnownProfileFields {

}
+ (NSString *)getStorageValueForField:(KnownField)field {
switch (field) {
case Name:
return CLTAP_USER_NAME;
case Email:
return CLTAP_USER_EMAIL;
case Education:
return CLTAP_USER_EDUCATION;
case Married:
return CLTAP_USER_MARRIED;
case DOB:
return CLTAP_USER_DOB;
case Birthday:
return CLTAP_USER_BIRTHDAY;
case Employed:
return CLTAP_USER_EMPLOYED;
case Gender:
return CLTAP_USER_GENDER;
case Phone:
return CLTAP_USER_PHONE;
case Age:
return CLTAP_USER_AGE;
default:
return nil;
}
}

+ (KnownField)getKnownFieldIfPossibleForKey:(NSString *)key {
if ([key isEqualToString:@"Name"])
Expand Down
26 changes: 14 additions & 12 deletions CleverTapSDK/CTLocalDataStore.m
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ - (instancetype)initWithConfig:(CleverTapInstanceConfig *)config profileValues:(
[self runOnBackgroundQueue:^{
@synchronized (self->localProfileForSession) {
// migrate to new persisted ct-accid-guid-userprofile
[CTUserInfoMigrator migrateUserInfoFileForAccountID:self->_config.accountId deviceID:self->_deviceInfo.deviceId];

[CTUserInfoMigrator migrateUserInfoFileForDeviceID:self->_deviceInfo.deviceId config:self->_config];
self->localProfileForSession = [self _inflateLocalProfile];
for (NSString* key in [profileValues allKeys]) {
[self setProfileFieldWithKey:key andValue:profileValues[key]];
Expand Down Expand Up @@ -548,6 +547,11 @@ - (id)getProfileFieldForKey:(NSString *)key {
newValue = nil;
[self removeProfileFieldForKey:key];
}
else if ([commandIdentifier isEqualToString:kCLTAP_COMMAND_SET] ||
[commandIdentifier isEqualToString:kCLTAP_COMMAND_ADD] ||
[commandIdentifier isEqualToString:kCLTAP_COMMAND_REMOVE]) {
newValue = [CTProfileBuilder _constructLocalMultiValueWithOriginalValues:value forKey:key usingCommand:commandIdentifier localDataStore:self];
}
} else if ([newValue isKindOfClass:[NSString class]]) {
// Remove the date prefix before evaluation and persisting
NSString *newValueStr = (NSString *)newValue;
Expand Down Expand Up @@ -707,7 +711,7 @@ - (NSString *)profileFileName {
}

- (NSMutableDictionary *)_inflateLocalProfile {
NSSet *allowedClasses = [NSSet setWithObjects:[NSString class], [NSMutableDictionary class], nil];
NSSet *allowedClasses = [NSSet setWithObjects:[NSArray class], [NSString class], [NSDictionary class], [NSNumber class], nil];
NSMutableDictionary *_profile = (NSMutableDictionary *)[CTPreferences unarchiveFromFile:[self profileFileName] ofTypes:allowedClasses removeFile:NO];
if (!_profile) {
_profile = [NSMutableDictionary dictionary];
Expand Down Expand Up @@ -904,18 +908,16 @@ - (void)addPropertyFromStoreIfExists:(NSString *)profileKey

- (NSDictionary*)generateBaseProfile {
NSMutableDictionary *profile = [NSMutableDictionary new];
[self addPropertyFromStoreIfExists:@"Name" profile:profile storageKeys:@[CLTAP_USER_NAME, CLTAP_FB_NAME, CLTAP_GP_NAME]];
[self addPropertyFromStoreIfExists:@"Gender" profile:profile storageKeys:@[CLTAP_USER_GENDER, CLTAP_FB_GENDER, CLTAP_GP_GENDER]];
[self addPropertyFromStoreIfExists:@"Education" profile:profile storageKeys:@[CLTAP_USER_EDUCATION, CLTAP_FB_EDUCATION]];
[self addPropertyFromStoreIfExists:@"Employed" profile:profile storageKeys:@[CLTAP_USER_EMPLOYED, CLTAP_FB_EMPLOYED, CLTAP_GP_EMPLOYED]];
[self addPropertyFromStoreIfExists:@"Married" profile:profile storageKeys:@[CLTAP_USER_MARRIED, CLTAP_FB_MARRIED, CLTAP_GP_MARRIED]];
[self addPropertyFromStoreIfExists:@"DOB" profile:profile storageKeys:@[CLTAP_USER_DOB, CLTAP_FB_DOB, CLTAP_GP_DOB]];
[self addPropertyFromStoreIfExists:@"Name" profile:profile storageKeys:@[CLTAP_USER_NAME]];
[self addPropertyFromStoreIfExists:@"Gender" profile:profile storageKeys:@[CLTAP_USER_GENDER]];
[self addPropertyFromStoreIfExists:@"Education" profile:profile storageKeys:@[CLTAP_USER_EDUCATION]];
[self addPropertyFromStoreIfExists:@"Employed" profile:profile storageKeys:@[CLTAP_USER_EMPLOYED]];
[self addPropertyFromStoreIfExists:@"Married" profile:profile storageKeys:@[CLTAP_USER_MARRIED]];
[self addPropertyFromStoreIfExists:@"DOB" profile:profile storageKeys:@[CLTAP_USER_DOB]];
[self addPropertyFromStoreIfExists:@"Birthday" profile:profile storageKeys:@[CLTAP_USER_BIRTHDAY]];
[self addPropertyFromStoreIfExists:@"FBID" profile:profile storageKeys:@[CLTAP_FB_ID]];
[self addPropertyFromStoreIfExists:@"GPID" profile:profile storageKeys:@[CLTAP_GP_ID]];
[self addPropertyFromStoreIfExists:@"Phone" profile:profile storageKeys:@[CLTAP_USER_PHONE]];
[self addPropertyFromStoreIfExists:@"Age" profile:profile storageKeys:@[CLTAP_USER_AGE]];
[self addPropertyFromStoreIfExists:@"Email" profile:profile storageKeys:@[CLTAP_USER_EMAIL, CLTAP_FB_EMAIL]];
[self addPropertyFromStoreIfExists:@"Email" profile:profile storageKeys:@[CLTAP_USER_EMAIL]];
[self addPropertyFromStoreIfExists:@"tz" profile:profile storageKeys:@[CLTAP_SYS_TZ]];
[self addPropertyFromStoreIfExists:@"Carrier" profile:profile storageKeys:@[CLTAP_SYS_CARRIER]];
[self addPropertyFromStoreIfExists:@"cc" profile:profile storageKeys:@[CLTAP_SYS_CC]];
Expand Down
2 changes: 2 additions & 0 deletions CleverTapSDK/CTProfileBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@

+ (NSNumber *_Nullable)_getUpdatedValue:(NSNumber *_Nonnull)value forKey:(NSString *_Nonnull)key withCommand:(NSString *_Nonnull)command cachedValue:(id _Nullable)cachedValue;

+ (NSArray<NSString *> *_Nullable) _constructLocalMultiValueWithOriginalValues:(NSArray * _Nonnull)values forKey:(NSString * _Nonnull)key usingCommand:(NSString * _Nonnull)command localDataStore:(CTLocalDataStore* _Nonnull)dataStore;

@end
2 changes: 1 addition & 1 deletion CleverTapSDK/CTProfileBuilder.m
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ + (void)build:(NSDictionary *)profile completionHandler:(void(^ _Nonnull )(NSDic
// if a reserved key add to systemFields else add to customFields
KnownField kf = [CTKnownProfileFields getKnownFieldIfPossibleForKey:key];
if (kf != UNKNOWN) {
systemFields[[CTKnownProfileFields getStorageValueForField:kf]] = value;
systemFields[key] = value;
} else {
customFields[key] = value;
}
Expand Down
3 changes: 2 additions & 1 deletion CleverTapSDK/CTUserInfoMigrator.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
//

#import <Foundation/Foundation.h>
#import "CleverTapInstanceConfig.h"

@interface CTUserInfoMigrator : NSObject

+ (void)migrateUserInfoFileForAccountID:(NSString *)acc_id deviceID:(NSString *)device_id;
+ (void)migrateUserInfoFileForDeviceID:(NSString *)device_id config:(CleverTapInstanceConfig *) config;

@end
46 changes: 44 additions & 2 deletions CleverTapSDK/CTUserInfoMigrator.m
Original file line number Diff line number Diff line change
@@ -1,26 +1,68 @@
#import "CTUserInfoMigrator.h"
#import "CTConstants.h"
#import "CTPreferences.h"

@implementation CTUserInfoMigrator

+ (void)migrateUserInfoFileForAccountID:(NSString *)acc_id deviceID:(NSString *)device_id {
+ (void)migrateUserInfoFileForDeviceID:(NSString *)device_id config:(CleverTapInstanceConfig *) config {
NSString *acc_id = config.accountId;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libraryPath = [paths objectAtIndex:0];
NSString *userProfileWithAccountID = [NSString stringWithFormat:@"clevertap-%@-userprofile.plist", acc_id];
NSString *userProfileWithAccountIDPath = [libraryPath stringByAppendingPathComponent:userProfileWithAccountID];
NSString *userProfileWithAccountIDAndDeviceID = [NSString stringWithFormat:@"clevertap-%@-%@-userprofile.plist", acc_id, device_id];
NSString *userProfileWithAccountIDAndDeviceIDPath = [libraryPath stringByAppendingPathComponent:userProfileWithAccountIDAndDeviceID];

NSError *error = nil;

// migration from 5.x and 6.x
if ([fileManager fileExistsAtPath:userProfileWithAccountIDPath]) {
// unarchive, remove user prefix, copy to new deviceid path
NSSet *allowedClasses = [NSSet setWithObjects:[NSArray class], [NSString class], [NSDictionary class], [NSNumber class], nil];
NSMutableDictionary *userProfile = [CTPreferences unarchiveFromFile:userProfileWithAccountID ofTypes:allowedClasses removeFile:NO];
// remove prefixes from only the system fields
[self removeUserPrefixInDictionary:userProfile];
// store this new clean file at userProfileWithAccountIDAndDeviceIDPath
[CTPreferences archiveObject:userProfile forFileName:userProfileWithAccountID config:config];
[fileManager copyItemAtPath:userProfileWithAccountIDPath toPath:userProfileWithAccountIDAndDeviceIDPath error:&error];
CleverTapLogStaticInternal(@"[CTUserInfo]: Local file copied successfully to %@", userProfileWithAccountIDAndDeviceIDPath);
[fileManager removeItemAtPath:userProfileWithAccountIDPath error:&error];
return;
}

// migration from 7.0.0
else if ([fileManager fileExistsAtPath:userProfileWithAccountIDAndDeviceIDPath]) {
// unarchive the file at this path
NSSet *allowedClasses = [NSSet setWithObjects:[NSArray class], [NSString class], [NSDictionary class], [NSNumber class], nil];
NSMutableDictionary *userProfile = [CTPreferences unarchiveFromFile:userProfileWithAccountIDAndDeviceID ofTypes:allowedClasses removeFile:NO];
// remove prefixes from only the system fields
[self removeUserPrefixInDictionary:userProfile];
// update the new file at userProfileWithAccountIDAndDeviceIDPath
[CTPreferences archiveObject:userProfile forFileName:userProfileWithAccountIDAndDeviceID config:config];
return;
} else {
CleverTapLogStaticInternal(@"[CTUserInfo]: Failed to copy local file: %@", error.localizedDescription);
}
}

+ (void)removeUserPrefixInDictionary:(NSMutableDictionary *)dictionary {
// List of known profile fields
NSArray *knownProfileFields = @[
@"userName", @"userEmail", @"userEducation", @"userMarried",
@"userDOB", @"userBirthday", @"userEmployed", @"userGender",
@"userPhone", @"userAge"
];

// Iterate through the original dictionary's keys
for (NSString *key in [dictionary allKeys]) {
if ([knownProfileFields containsObject:key]) {
NSString *newKey = [key substringFromIndex:[@"user" length]];

// Update the dictionary with the new key
id value = dictionary[key];
[dictionary removeObjectForKey:key];
[dictionary setObject:value forKey:newKey];
}
}
}
@end
10 changes: 5 additions & 5 deletions CleverTapSDK/CleverTap.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,16 +373,16 @@ extern NSString * _Nonnull const CleverTapGeofencesDidUpdateNotification;
@method
@abstract
Creates a separate and distinct user profile identified by one or more of Identity, Email, FBID or GPID values,
Creates a separate and distinct user profile identified by one or more of Identity or Email values,
and populated with the key-values included in the properties dictionary.
@discussion
If your app is used by multiple users, you can use this method to assign them each a unique profile to track them separately.
If instead you wish to assign multiple Identity, Email, FBID and/or GPID values to the same user profile,
If instead you wish to assign multiple Identity and/or Email values to the same user profile,
use profilePush rather than this method.
If none of Identity, Email, FBID or GPID is included in the properties dictionary,
If none of Identity or Email is included in the properties dictionary,
all properties values will be associated with the current user profile.
When initially installed on this device, your app is assigned an "anonymous" profile.
Expand Down Expand Up @@ -412,10 +412,10 @@ extern NSString * _Nonnull const CleverTapGeofencesDidUpdateNotification;
@discussion
If your app is used by multiple users, you can use this method to assign them each a unique profile to track them separately.
If instead you wish to assign multiple Identity, Email, FBID and/or GPID values to the same user profile,
If instead you wish to assign multiple Identity and/or Email values to the same user profile,
use profilePush rather than this method.
If none of Identity, Email, FBID or GPID is included in the properties dictionary,
If none of Identity or Email is included in the properties dictionary,
all properties values will be associated with the current user profile.
When initially installed on this device, your app is assigned an "anonymous" profile.
Expand Down
2 changes: 1 addition & 1 deletion CleverTapSDK/CleverTapBuildInfo.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define WR_SDK_REVISION @"70000"
#define WR_SDK_REVISION @"70001"
9 changes: 6 additions & 3 deletions CleverTapSDKTests/CTUserInfoMigratorTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
#import <XCTest/XCTest.h>
#import "CTUserInfoMigrator.h"
#import "XCTestCase+XCTestCase_Tests.h"
#import "CleverTapInstanceConfig.h"

@interface CTUserInfoMigratorTest : XCTestCase

@property (nonatomic, strong) NSFileManager *fileManager;
@property (nonatomic, strong) NSString *libraryPath;
@property (nonatomic, strong) CleverTapInstanceConfig *config;

@end

Expand All @@ -27,6 +29,7 @@ - (void)setUp {
// Get the path to the Library directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
self.libraryPath = [paths objectAtIndex:0];
self.config = [[CleverTapInstanceConfig alloc] initWithAccountId:@"testAccID" accountToken:@"testToken" accountRegion:@"testRegion"];
}

- (void)tearDown {
Expand All @@ -52,7 +55,7 @@ - (void)testMigrateUserInfoFileForAccountID_WhenOldFileExists_ShouldCopyToNewLoc
[self.fileManager createFileAtPath:oldFilePath contents:[@"old content" dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];

// Call the method to migrate the user info file
[CTUserInfoMigrator migrateUserInfoFileForAccountID:acc_id deviceID:device_id];
[CTUserInfoMigrator migrateUserInfoFileForDeviceID:device_id config:self.config];

// Check that the old file has been copied to the new location
NSString *newFileName = [NSString stringWithFormat:@"clevertap-%@-%@-userprofile.plist", acc_id, device_id];
Expand All @@ -77,7 +80,7 @@ - (void)testMigrateUserInfoFileForAccountID_WhenNewFileExists_ShouldNotCopyAndDe
[self.fileManager createFileAtPath:newFilePath contents:[@"new content" dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];

// Call the method to migrate the user info file
[CTUserInfoMigrator migrateUserInfoFileForAccountID:acc_id deviceID:device_id];
[CTUserInfoMigrator migrateUserInfoFileForDeviceID:device_id config:self.config];

// Check that the new file still exists
XCTAssertTrue([self.fileManager fileExistsAtPath:newFilePath], @"New plist file should exist");
Expand All @@ -96,7 +99,7 @@ - (void)testMigrateUserInfoFileForAccountID_WhenOldFileDoesNotExist_ShouldNotCre
[self.fileManager removeItemAtPath:oldFilePath error:nil];

// Call the method to migrate the user info file
[CTUserInfoMigrator migrateUserInfoFileForAccountID:acc_id deviceID:device_id];
[CTUserInfoMigrator migrateUserInfoFileForDeviceID:device_id config:self.config];

// Check that the new file does not exist
NSString *newFileName = [NSString stringWithFormat:@"clevertap-%@-%@-userprofile.plist", acc_id, device_id];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef CTCustomTemplatesManager_Tests_h
#define CTCustomTemplatesManager_Tests_h
#import "CTCustomTemplatesManager.h"
#import "CTCustomTemplatesManager-Internal.h"

@interface CTCustomTemplatesManager (Tests)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

#import <Foundation/Foundation.h>
#import <XCTest/XCTest.h>
#import "CTCustomTemplatesManager-Internal.h"
#import "CTCustomTemplatesManager+Tests.h"
#import "CTInAppTemplateBuilder.h"
#import "CTAppFunctionBuilder.h"
Expand Down
2 changes: 1 addition & 1 deletion sdk-version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.0.0
7.0.1

0 comments on commit 7c6ec5f

Please sign in to comment.