Skip to content

Commit 072e157

Browse files
authored
fix(leanplum): Record attribute exception LP-7622 (#114)
1 parent a67d90e commit 072e157

File tree

1 file changed

+33
-30
lines changed

1 file changed

+33
-30
lines changed

Leanplum-SDK/Classes/Leanplum.m

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,9 @@ + (void)reset
692692
[state.noDownloadsBlocks removeAllObjects];
693693
[state.onceNoDownloadsBlocks removeAllObjects];
694694
[state.noDownloadsResponders removeAllObjects];
695-
[state.userAttributeChanges removeAllObjects];
695+
@synchronized([LPInternalState sharedState].userAttributeChanges) {
696+
[state.userAttributeChanges removeAllObjects];
697+
}
696698
state.calledHandleNotification = NO;
697699

698700
[[LPInbox sharedState] reset];
@@ -775,7 +777,9 @@ + (void)startWithUserId:(NSString *)userId
775777
[LPMessageTemplatesClass sharedTemplates];
776778
attributes = [self validateAttributes:attributes named:@"userAttributes" allowLists:YES];
777779
if (attributes != nil) {
778-
[state.userAttributeChanges addObject:attributes];
780+
@synchronized([LPInternalState sharedState].userAttributeChanges) {
781+
[state.userAttributeChanges addObject:attributes];
782+
}
779783
}
780784
state.calledStart = YES;
781785
dispatch_async(dispatch_get_main_queue(), ^{
@@ -2017,12 +2021,14 @@ + (void)setUserId:(NSString *)userId withUserAttributes:(NSDictionary *)attribut
20172021
[self throwError:@"You cannot call setUserId before calling start"];
20182022
return;
20192023
}
2024+
LP_END_USER_CODE // Catch when setUser is called in start response.
20202025
LP_TRY
20212026
attributes = [self validateAttributes:attributes named:@"userAttributes" allowLists:YES];
20222027
[self onStartIssued:^{
20232028
[self setUserIdInternal:userId withAttributes:attributes];
20242029
}];
20252030
LP_END_TRY
2031+
LP_BEGIN_USER_CODE
20262032
}
20272033

20282034
+ (void)setUserIdInternal:(NSString *)userId withAttributes:(NSDictionary *)attributes
@@ -2052,7 +2058,9 @@ + (void)setUserIdInternal:(NSString *)userId withAttributes:(NSDictionary *)attr
20522058
}
20532059

20542060
if (attributes != nil) {
2055-
[[LPInternalState sharedState].userAttributeChanges addObject:attributes];
2061+
@synchronized([LPInternalState sharedState].userAttributeChanges) {
2062+
[[LPInternalState sharedState].userAttributeChanges addObject:attributes];
2063+
}
20562064
}
20572065

20582066
[Leanplum onStartResponse:^(BOOL success) {
@@ -2066,35 +2074,30 @@ + (void)setUserIdInternal:(NSString *)userId withAttributes:(NSDictionary *)attr
20662074
// Returns if attributes have changed.
20672075
+ (void)recordAttributeChanges
20682076
{
2069-
BOOL madeChanges = NO;
2070-
// Making a copy. Other threads can add attributes while iterating.
2071-
NSMutableArray *attributeChanges = [[LPInternalState sharedState].userAttributeChanges copy];
2072-
// Keep track of processed changes to be removed at the end.
2073-
NSMutableArray *processedChanges = [NSMutableArray new];
2074-
for (NSDictionary *attributes in attributeChanges) {
2077+
@synchronized([LPInternalState sharedState].userAttributeChanges){
2078+
BOOL __block madeChanges = NO;
20752079
NSMutableDictionary *existingAttributes = [LPVarCache userAttributes];
2076-
[processedChanges addObject:attributes];
2077-
for (NSString *attributeName in [attributes allKeys]) {
2078-
id existingValue = existingAttributes[attributeName];
2079-
id value = attributes[attributeName];
2080-
if (![value isEqual:existingValue]) {
2081-
LPContextualValues *contextualValues = [[LPContextualValues alloc] init];
2082-
contextualValues.previousAttributeValue = existingValue;
2083-
contextualValues.attributeValue = value;
2084-
existingAttributes[attributeName] = value;
2085-
[Leanplum maybePerformActions:@[@"userAttribute"]
2086-
withEventName:attributeName
2087-
withFilter:kLeanplumActionFilterAll
2088-
fromMessageId:nil
2089-
withContextualValues:contextualValues];
2090-
madeChanges = YES;
2091-
}
2080+
for (NSDictionary *attributes in [LPInternalState sharedState].userAttributeChanges) {
2081+
[attributes enumerateKeysAndObjectsUsingBlock:^(id attributeName, id value, BOOL *stop) {
2082+
id existingValue = existingAttributes[attributeName];
2083+
if (![value isEqual:existingValue]) {
2084+
LPContextualValues *contextualValues = [LPContextualValues new];
2085+
contextualValues.previousAttributeValue = existingValue;
2086+
contextualValues.attributeValue = value;
2087+
existingAttributes[attributeName] = value;
2088+
[Leanplum maybePerformActions:@[@"userAttribute"]
2089+
withEventName:attributeName
2090+
withFilter:kLeanplumActionFilterAll
2091+
fromMessageId:nil
2092+
withContextualValues:contextualValues];
2093+
madeChanges = YES;
2094+
}
2095+
}];
2096+
}
2097+
[[LPInternalState sharedState].userAttributeChanges removeAllObjects];
2098+
if (madeChanges) {
2099+
[LPVarCache saveUserAttributes];
20922100
}
2093-
}
2094-
// Remove only processed changes.
2095-
[[LPInternalState sharedState].userAttributeChanges removeObjectsInArray:processedChanges];
2096-
if (madeChanges) {
2097-
[LPVarCache saveUserAttributes];
20982101
}
20992102
}
21002103

0 commit comments

Comments
 (0)