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

Release 7.0.3 #390

Merged
merged 27 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3d9748f
Added push and pop validation in synchronized block
kushCT Oct 29, 2024
3ebb17f
chore(MC-2302): Update HTML template for inapp preview.
nishant-clevertap Nov 7, 2024
5f26cf6
Use weak reference check for controller hide (#379)
nzagorchev Nov 7, 2024
db45c6c
task(MC-2359): Add normalized event and property names evaluation
nishant-clevertap Nov 14, 2024
4c1e69a
Add normalized names check to restricted and discarded events check.
nishant-clevertap Nov 14, 2024
909b924
Added method docs and comment.
nishant-clevertap Nov 14, 2024
b44db16
- Updated to latest HTML preview template.
nishant-clevertap Nov 19, 2024
4958189
Merge pull request #378 from CleverTap/fix/SDK-4102-validation-stack-fix
akashvercetti Nov 20, 2024
d8773c2
added support for promptForPushPermission method in JS Interface
akashvercetti Nov 22, 2024
99a149f
dismissed inapp when the prompt method is called from an html in-app
akashvercetti Nov 22, 2024
a87ad48
- Added normalisation for event property name also.
nishant-clevertap Nov 22, 2024
a9ad294
Refactor test push inapp handling
nzagorchev Nov 26, 2024
aecb5bd
Merge pull request #387 from CleverTap/SDK-4182-promptForPushPermissi…
akashvercetti Nov 26, 2024
2626df0
Merge pull request #383 from CleverTap/task/update_inapp_html_preview
akashvercetti Nov 26, 2024
7ccb4cd
added normalisation for charged event items
akashvercetti Nov 26, 2024
1e6c80d
[MC-2363] Add parsing of url params on open-url action (#386)
nishant-clevertap Nov 26, 2024
0b0ed32
Normalize event properties and items
nzagorchev Nov 27, 2024
7570b47
Add profile attribute name normalization tests
nzagorchev Nov 27, 2024
3c2778d
added setCredentials method for custom handshake domain
akashvercetti Nov 28, 2024
6bf58a8
Merge branch 'develop' into task/compare_normalized_event_names
akashvercetti Nov 28, 2024
ee13bfe
Merge pull request #385 from CleverTap/task/compare_normalized_event_…
akashvercetti Nov 28, 2024
99f7318
Merge pull request #388 from CleverTap/add-setcredential-custom-domain
akashvercetti Nov 28, 2024
e1745f1
changelog and version changes
akashvercetti Nov 28, 2024
ca2f508
Update CHANGELOG.md
akashvercetti Nov 29, 2024
61192c2
Update CHANGELOG.md
akashvercetti Nov 29, 2024
7b4f9e6
Update CHANGELOG.md
akashvercetti Nov 29, 2024
6ba80a3
Merge pull request #389 from CleverTap/prepare-7.0.3
akashvercetti Nov 29, 2024
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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
# Change Log
All notable changes to this project will be documented in this file.

### [Version 7.0.3](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/7.0.3) (November 29, 2024)

#### Added
- Adds a method `setCredentials` for setting custom handshake domains.
- Adds support for previewing in-apps created through the new dashboard advanced builder.
- Adds parsing of urls for `open-url` action to track parameters in the url for `Notification Clicked` events in HTML in-app messages.
- Adds support for `promptForPushPermission` method in JS Interface and HTML in-apps.

#### Fixed
- Mitigates a potential crash related to the `CTValidationResultStack` class.
- Mitigates a potential crash on `[CTInAppHTMLViewController hideFromWindow:]`.
- Changes campaign triggering evaluation of event names, event properties, and profile properties to ignore letter case and whitespace.
- Fixes an issue where the `wzrk_c2a` value is passed as null to backend when we receive null for `callToAction` value in a webView message handler.

### [Version 7.0.2](https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/7.0.2) (October 10, 2024)

#### Added
Expand Down
14 changes: 14 additions & 0 deletions CleverTapSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
32790959299F4B29001FE140 /* CTDeviceInfoTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 32790958299F4B29001FE140 /* CTDeviceInfoTest.m */; };
4803951B2A7ABAD200C4D254 /* CTAES.m in Sources */ = {isa = PBXBuildFile; fileRef = 480395192A7ABAD200C4D254 /* CTAES.m */; };
4803951C2A7ABAD200C4D254 /* CTAES.h in Headers */ = {isa = PBXBuildFile; fileRef = 4803951A2A7ABAD200C4D254 /* CTAES.h */; };
4806346F2CEB620400E39E9B /* CTInAppDisplayViewControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4806346E2CEB620400E39E9B /* CTInAppDisplayViewControllerTests.m */; };
4808030E292EB4FB00C06E2F /* CleverTap+PushPermission.h in Headers */ = {isa = PBXBuildFile; fileRef = 4808030D292EB4FB00C06E2F /* CleverTap+PushPermission.h */; };
48080311292EB50D00C06E2F /* CTLocalInApp.h in Headers */ = {isa = PBXBuildFile; fileRef = 4808030F292EB50D00C06E2F /* CTLocalInApp.h */; settings = {ATTRIBUTES = (Public, ); }; };
48080312292EB50D00C06E2F /* CTLocalInApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 48080310292EB50D00C06E2F /* CTLocalInApp.m */; };
Expand Down Expand Up @@ -349,6 +350,8 @@
6B32A0AD2B9DBE31009ADC57 /* CTTemplatePresenterMock.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B32A0AC2B9DBE31009ADC57 /* CTTemplatePresenterMock.m */; };
6B32A0B02B9DC374009ADC57 /* CTTemplateArgumentTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B32A0AF2B9DC374009ADC57 /* CTTemplateArgumentTest.m */; };
6B32A0B42B9F2E8F009ADC57 /* CTTestTemplateProducer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B32A0B32B9F2E8F009ADC57 /* CTTestTemplateProducer.m */; };
6B453EFE2CF74BE2003C7A89 /* CTEventAdapterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B453EFD2CF74BE2003C7A89 /* CTEventAdapterTest.m */; };
6B453EF92CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B453EF82CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.m */; };
6B4A0F912B45EF6D00A42C6D /* CTInAppTriggerManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B4A0F902B45EF6D00A42C6D /* CTInAppTriggerManagerTest.m */; };
6B535FB62AD56C60002A2663 /* CTMultiDelegateManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B535FB42AD56C60002A2663 /* CTMultiDelegateManager.h */; };
6B535FB72AD56C60002A2663 /* CTMultiDelegateManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B535FB42AD56C60002A2663 /* CTMultiDelegateManager.h */; };
Expand Down Expand Up @@ -769,6 +772,7 @@
32790958299F4B29001FE140 /* CTDeviceInfoTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTDeviceInfoTest.m; sourceTree = "<group>"; };
480395192A7ABAD200C4D254 /* CTAES.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CTAES.m; sourceTree = "<group>"; };
4803951A2A7ABAD200C4D254 /* CTAES.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CTAES.h; sourceTree = "<group>"; };
4806346E2CEB620400E39E9B /* CTInAppDisplayViewControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTInAppDisplayViewControllerTests.m; sourceTree = "<group>"; };
4808030D292EB4FB00C06E2F /* CleverTap+PushPermission.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CleverTap+PushPermission.h"; sourceTree = "<group>"; };
4808030F292EB50D00C06E2F /* CTLocalInApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CTLocalInApp.h; sourceTree = "<group>"; };
48080310292EB50D00C06E2F /* CTLocalInApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CTLocalInApp.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -911,6 +915,9 @@
6B32A0B12B9F2A75009ADC57 /* CTCustomTemplatesManager+Tests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CTCustomTemplatesManager+Tests.h"; sourceTree = "<group>"; };
6B32A0B22B9F2E8F009ADC57 /* CTTestTemplateProducer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CTTestTemplateProducer.h; sourceTree = "<group>"; };
6B32A0B32B9F2E8F009ADC57 /* CTTestTemplateProducer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTTestTemplateProducer.m; sourceTree = "<group>"; };
6B453EFD2CF74BE2003C7A89 /* CTEventAdapterTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTEventAdapterTest.m; sourceTree = "<group>"; };
6B453EF72CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CTInAppDisplayViewControllerMock.h; sourceTree = "<group>"; };
6B453EF82CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTInAppDisplayViewControllerMock.m; sourceTree = "<group>"; };
6B4A0F902B45EF6D00A42C6D /* CTInAppTriggerManagerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTInAppTriggerManagerTest.m; sourceTree = "<group>"; };
6B535FB42AD56C60002A2663 /* CTMultiDelegateManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CTMultiDelegateManager.h; sourceTree = "<group>"; };
6B535FB52AD56C60002A2663 /* CTMultiDelegateManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTMultiDelegateManager.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1471,6 +1478,10 @@
6BA3B2E72B07E207004E834B /* CTTriggersMatcher+Tests.m */,
6B4A0F902B45EF6D00A42C6D /* CTInAppTriggerManagerTest.m */,
6BB778CF2BEE4C3400A41628 /* CTNotificationActionTest.m */,
6B453EFD2CF74BE2003C7A89 /* CTEventAdapterTest.m */,
4806346E2CEB620400E39E9B /* CTInAppDisplayViewControllerTests.m */,
6B453EF72CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.h */,
6B453EF82CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.m */,
);
path = InApps;
sourceTree = "<group>";
Expand Down Expand Up @@ -2525,17 +2536,20 @@
6B32A0A32B99EA9D009ADC57 /* CTCustomTemplateBuilderTest.m in Sources */,
6B9E95B52C29C2F40002D557 /* NSFileManagerMock.m in Sources */,
6A7BB8DC29E47CFF00651584 /* CTVarTest.m in Sources */,
6B453EF92CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.m in Sources */,
6B32A0AD2B9DBE31009ADC57 /* CTTemplatePresenterMock.m in Sources */,
6A2E0B9129CCCC8600FCEA5F /* ContentMergerTest.m in Sources */,
6A2E0B9529D49D0200FCEA5F /* CTVariables+Tests.m in Sources */,
6B32A0B42B9F2E8F009ADC57 /* CTTestTemplateProducer.m in Sources */,
6A2E0B9829D49D5100FCEA5F /* CTVarCacheMock.m in Sources */,
4EAF05022A495DD5009D9D61 /* CleverTapInstanceTests.m in Sources */,
6BB778D22BF267B600A41628 /* CTTemplateContextTest.m in Sources */,
4806346F2CEB620400E39E9B /* CTInAppDisplayViewControllerTests.m in Sources */,
6A2E0B9329D0A5CF00FCEA5F /* CTVariablesTest.m in Sources */,
D02AC2DB276044F70031C1BE /* CleverTapSDKTests.m in Sources */,
32394C2129FA264B00956058 /* CTPreferencesTest.m in Sources */,
6BD334F02AF545C80099E33E /* CTInAppStoreTest.m in Sources */,
6B453EFE2CF74BE2003C7A89 /* CTEventAdapterTest.m in Sources */,
32394C1F29FA251E00956058 /* CTEventBuilderTest.m in Sources */,
6B12F7692C9466460045D743 /* CTJsonTemplateProducerTest.m in Sources */,
6BB778D02BEE4C3400A41628 /* CTNotificationActionTest.m in Sources */,
Expand Down
3 changes: 3 additions & 0 deletions CleverTapSDK/CTConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,13 @@ extern NSString *CLTAP_PROFILE_IDENTITY_KEY;

#define CLTAP_INAPP_PREVIEW_TYPE @"wzrk_inapp_type"
#define CLTAP_INAPP_IMAGE_INTERSTITIAL_TYPE @"image-interstitial"
#define CLTAP_INAPP_ADVANCED_BUILDER_TYPE @"advanced-builder"
#define CLTAP_INAPP_IMAGE_INTERSTITIAL_CONFIG @"imageInterstitialConfig"
#define CLTAP_INAPP_HTML_SPLIT @"\"##Vars##\""
#define CLTAP_INAPP_IMAGE_INTERSTITIAL_HTML_NAME @"image_interstitial"

#define CLTAP_URL_PARAM_DL_SEPARATOR @"__dl__"

#pragma mark Constants for persisting system data
#define CLTAP_SYS_CARRIER @"sysCarrier"
#define CLTAP_SYS_CC @"sysCountryCode"
Expand Down
41 changes: 35 additions & 6 deletions CleverTapSDK/CTInAppDisplayViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,30 @@ - (void)showFromWindow:(BOOL)animated {
}

- (void)hideFromWindow:(BOOL)animated {
[self hideFromWindow:animated withCompletion:nil];
}

- (void)hideFromWindow:(BOOL)animated withCompletion:(void (^)(void))completion {
__weak typeof(self) weakSelf = self;
void (^completionBlock)(void) = ^ {
[self.window removeFromSuperview];
self.window = nil;
if (self.delegate && [self.delegate respondsToSelector:@selector(notificationDidDismiss:fromViewController:)]) {
[self.delegate notificationDidDismiss:self.notification fromViewController:self];
if (!weakSelf) {
return;
}
if (weakSelf.window) {
[weakSelf.window removeFromSuperview];
weakSelf.window = nil;
}
if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(notificationDidDismiss:fromViewController:)]) {
[weakSelf.delegate notificationDidDismiss:weakSelf.notification fromViewController:weakSelf];
}
if (completion) {
completion();
}
};

if (animated) {
[UIView animateWithDuration:0.25 animations:^{
self.window.alpha = 0;
weakSelf.window.alpha = 0;
} completion:^(BOOL finished) {
completionBlock();
}];
Expand All @@ -216,7 +229,6 @@ - (void)hideFromWindow:(BOOL)animated {
}
}


#pragma mark - CTInAppPassThroughViewDelegate

- (void)viewWillPassThroughTouch {
Expand Down Expand Up @@ -303,6 +315,23 @@ - (void)handleButtonClickFromIndex:(int)index {

- (void)triggerInAppAction:(CTNotificationAction *)action callToAction:(NSString *)callToAction buttonId:(NSString *)buttonId {
NSMutableDictionary *extras = [NSMutableDictionary new];

if (action.type == CTInAppActionTypeOpenURL) {
NSString *urlString = [action.actionURL absoluteString];
NSMutableDictionary *mutableParams = [CTInAppUtils getParametersFromURL:urlString];

if (mutableParams[@"params"]) {
extras = [mutableParams[@"params"] mutableCopy];

// Use the url from the deeplink to update the action if such is set
if (mutableParams[@"deeplink"]) {
action = [[CTNotificationAction alloc] initWithOpenURL:mutableParams[@"deeplink"]];
}
}
}

// callToAction, buttonId and notification id take precedence over
// the URL parameters if those have been set in the URL
if (callToAction) {
extras[CLTAP_PROP_WZRK_CTA] = callToAction;
}
Expand Down
1 change: 1 addition & 0 deletions CleverTapSDK/CTInAppDisplayViewControllerPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

- (void)showFromWindow:(BOOL)animated;
- (void)hideFromWindow:(BOOL)animated;
- (void)hideFromWindow:(BOOL)animated withCompletion:(void (^)(void))completion;

- (void)tappedDismiss;
- (void)buttonTapped:(UIButton*)button;
Expand Down
10 changes: 8 additions & 2 deletions CleverTapSDK/CTInAppUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ typedef NS_ENUM(NSUInteger, CTInAppActionType){
+ (NSString * _Nonnull)inAppTypeString:(CTInAppType)type;
+ (CTInAppActionType)inAppActionTypeFromString:(NSString *_Nonnull)type;
+ (NSString * _Nonnull)inAppActionTypeString:(CTInAppActionType)type;
+ (NSBundle *_Nullable)bundle;
+ (NSString *_Nullable)getXibNameForControllerName:(NSString *_Nonnull)controllerName;
+ (NSBundle * _Nullable)bundle;
+ (NSString * _Nullable)getXibNameForControllerName:(NSString * _Nonnull)controllerName;
/**
* Extracts the parameters from the URL and extracts the deeplink from the call to action if applicable.
* @param url The URL to process.
* @return Returns a dictionary with "deeplink" and "params" keys holding the respective values.
*/
+ (NSMutableDictionary * _Nonnull)getParametersFromURL:(NSString * _Nonnull)url;

@end
31 changes: 31 additions & 0 deletions CleverTapSDK/CTInAppUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,35 @@ + (NSString *)getXibNameForControllerName:(NSString *)controllerName {
#endif
}

+ (NSMutableDictionary *)getParametersFromURL:(NSString *)urlString {
NSMutableDictionary *mutableParams = [[NSMutableDictionary alloc] init];
// Try to extract the parameters from the URL and overrite default dl if applicable
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
NSArray *comps = [urlString componentsSeparatedByString:@"?"];
if ([comps count] >= 2) {
// Extract the parameters and store in params dictionary
NSString *query = comps[1];
for (NSString *param in [query componentsSeparatedByString:@"&"]) {
NSArray *elts = [param componentsSeparatedByString:@"="];
if ([elts count] < 2) continue;
params[elts[0]] = [elts[1] stringByRemovingPercentEncoding];
}

// Check for wzrk_c2a key, if present update its value after parsing with __dl__
NSString *c2a = params[CLTAP_PROP_WZRK_CTA];
if (c2a) {
c2a = [c2a stringByRemovingPercentEncoding];
NSArray *parts = [c2a componentsSeparatedByString:CLTAP_URL_PARAM_DL_SEPARATOR];
if (parts && [parts count] == 2) {
params[CLTAP_PROP_WZRK_CTA] = parts[0];
mutableParams[@"deeplink"] = [NSURL URLWithString:parts[1]];
}
}

mutableParams[@"params"] = [params mutableCopy];
}

return mutableParams;
}

@end
2 changes: 1 addition & 1 deletion CleverTapSDK/CTPlistInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@
- (void)setCredentialsWithAccountID:(NSString * _Nonnull)accountID token:(NSString * _Nonnull)token region:(NSString * _Nullable)region;
- (void)setCredentialsWithAccountID:(NSString * _Nonnull)accountID token:(NSString * _Nonnull)token proxyDomain:(NSString * _Nonnull)proxyDomain;
- (void)setCredentialsWithAccountID:(NSString * _Nonnull)accountID token:(NSString * _Nonnull)token proxyDomain:(NSString * _Nonnull)proxyDomain spikyProxyDomain:(NSString * _Nullable)spikyProxyDomain;

- (void)setCredentialsWithAccountID:(NSString * _Nonnull)accountID token:(NSString * _Nonnull)token proxyDomain:(NSString * _Nonnull)proxyDomain spikyProxyDomain:(NSString * _Nullable)spikyProxyDomain handshakeDomain:(NSString* _Nonnull)handshakeDomain;
@end
8 changes: 8 additions & 0 deletions CleverTapSDK/CTPlistInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ - (void)setCredentialsWithAccountID:(NSString * _Nonnull)accountID token:(NSStri
_spikyProxyDomain = spikyProxyDomain;
}

- (void)setCredentialsWithAccountID:(NSString * _Nonnull)accountID token:(NSString * _Nonnull)token proxyDomain:(NSString * _Nonnull)proxyDomain spikyProxyDomain:(NSString * _Nullable)spikyProxyDomain handshakeDomain:(NSString*)handshakeDomain {
_accountId = accountID;
_accountToken = token;
_proxyDomain = proxyDomain;
_spikyProxyDomain = spikyProxyDomain;
_handshakeDomain = handshakeDomain;
}

- (void)setEncryption:(NSString *)encryptionLevel {
if (encryptionLevel && [encryptionLevel isEqualToString:@"0"]) {
_encryptionLevel = CleverTapEncryptionNone;
Expand Down
10 changes: 10 additions & 0 deletions CleverTapSDK/CTUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,14 @@
+ (NSNumber * _Nullable)numberFromString:(NSString * _Nullable)string;
+ (NSNumber * _Nullable)numberFromString:(NSString * _Nullable)string withLocale:(NSLocale * _Nullable)locale;

/**
* Get the CT normalized version of an event or a property name.
*/
+ (NSString * _Nullable)getNormalizedName:(NSString * _Nullable)name;

/**
* Check if two event/property names are equal with applied CT normalization
*/
+ (BOOL)areEqualNormalizedName:(NSString * _Nullable)firstName andName:(NSString * _Nullable)secondName;

@end
30 changes: 30 additions & 0 deletions CleverTapSDK/CTUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,34 @@ + (NSNumber * _Nullable)numberFromString:(NSString * _Nullable)string withLocale
return nil;
}

+ (NSString * _Nullable)getNormalizedName:(NSString * _Nullable)name {
if (name) {
// Lowercase with English locale for consistent behavior with the backend
// and across different device locales.
NSString *normalizedName = [name stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLocale *englishLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
normalizedName = [normalizedName lowercaseStringWithLocale:englishLocale];
normalizedName = [normalizedName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
return normalizedName;
}

return nil;
}

+ (BOOL)areEqualNormalizedName:(NSString * _Nullable)firstName
andName:(NSString * _Nullable)secondName {
if (firstName == nil && secondName == nil) {
return YES;
}

if (firstName == nil || secondName == nil) {
return NO;
}

NSString *normalizedFirstName = [CTUtils getNormalizedName:firstName];
NSString *normalizedSecondName = [CTUtils getNormalizedName:secondName];

return [normalizedFirstName isEqualToString:normalizedSecondName];
}

@end
20 changes: 13 additions & 7 deletions CleverTapSDK/CTValidationResultStack.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,26 @@ - (void)pushValidationResult:(CTValidationResult *)vr {
CleverTapLogInternal(self.config.logLevel, @"%@: no object in the validation result", self);
return;
}
[self.pendingValidationResults addObject:vr];
if (self.pendingValidationResults && [self.pendingValidationResults count] > 50) {
[self.pendingValidationResults removeObjectAtIndex:0];

@synchronized (self.pendingValidationResults) {
[self.pendingValidationResults addObject:vr];
if (self.pendingValidationResults.count > 50) {
[self.pendingValidationResults removeObjectAtIndex:0];
}
}
}

- (CTValidationResult *)popValidationResult {
CTValidationResult *vr = nil;
if (self.pendingValidationResults && [self.pendingValidationResults count] > 0) {
vr = self.pendingValidationResults[0];
[self.pendingValidationResults removeObjectAtIndex:0];

@synchronized (self.pendingValidationResults) {
if (self.pendingValidationResults.count > 0) {
vr = self.pendingValidationResults[0];
[self.pendingValidationResults removeObjectAtIndex:0];
}
}

return vr;
}


@end
Loading
Loading