@@ -44,92 +44,105 @@ + (void)addEventCallbackAt:(NSInteger)index
4444 onSuccess : (LPNetworkResponseBlock)responseBlock
4545 onError : (LPNetworkErrorBlock)errorBlock
4646{
47- if (!responseBlock && !errorBlock) {
48- return ;
49- }
50-
51- NSMutableDictionary *callbackMap = [LPEventCallbackManager eventCallbackMap ];
52- LPEventCallback *callback = [[LPEventCallback alloc ] initWithResponseBlock: responseBlock
53- errorBlock: errorBlock];
54- NSNumber *atIndex = @(index);
55-
56- if (callbackMap && callback && atIndex) {
57- callbackMap[atIndex] = callback;
47+ @synchronized ([LPEventCallbackManager eventCallbackMap ])
48+ {
49+ if (!responseBlock && !errorBlock) {
50+ return ;
51+ }
52+
53+ NSMutableDictionary *callbackMap = [LPEventCallbackManager eventCallbackMap ];
54+ LPEventCallback *callback = [[LPEventCallback alloc ] initWithResponseBlock: responseBlock
55+ errorBlock: errorBlock];
56+
57+ NSNumber *atIndex = @(index);
58+
59+ if (callbackMap && callback && atIndex) {
60+ callbackMap[atIndex] = callback;
61+ }
62+ [[LPCountAggregator sharedAggregator ] incrementCount: @" add_event_callback_at" ];
5863 }
59- [[LPCountAggregator sharedAggregator ] incrementCount: @" add_event_callback_at" ];
6064}
6165
6266+ (void )invokeSuccessCallbacksOnResponses : (id )responses
6367 requests : (NSArray *)requests
6468 operation : (id <LPNetworkOperationProtocol>)operation
6569{
66- // Invoke and remove the callbacks that have errors.
67- [LPEventCallbackManager invokeErrorCallbacksOnResponses: responses];
68-
69- NSMutableDictionary *callbackMap = [LPEventCallbackManager eventCallbackMap ];
70- NSMutableDictionary *updatedCallbackMap = [NSMutableDictionary new ];
71- NSMutableDictionary *activeResponseMap = [NSMutableDictionary new ];
72-
73- for (NSNumber *indexObject in callbackMap.allKeys ) {
74- NSInteger index = [indexObject integerValue ];
75- LPEventCallback *eventCallback = callbackMap[indexObject];
76-
77- // If index is in range, execute and remove it.
78- // If not, requests are in the future. Update the index.
79- [callbackMap removeObjectForKey: indexObject];
80- if (index >= requests.count ) {
81- index -= requests.count ;
82- updatedCallbackMap[@(index)] = eventCallback;
83- } else if (eventCallback.responseBlock ) {
84- activeResponseMap[indexObject] = [eventCallback.responseBlock copy ];
70+ @synchronized ([LPEventCallbackManager eventCallbackMap ])
71+ {
72+ // Invoke and remove the callbacks that have errors.
73+ [LPEventCallbackManager invokeErrorCallbacksOnResponses: responses];
74+
75+ NSMutableDictionary *callbackMap = [LPEventCallbackManager eventCallbackMap ];
76+ NSMutableDictionary *updatedCallbackMap = [NSMutableDictionary new ];
77+ NSMutableDictionary *activeResponseMap = [NSMutableDictionary new ];
78+
79+ for (NSNumber *indexObject in callbackMap.allKeys ) {
80+ NSInteger index = [indexObject integerValue ];
81+ LPEventCallback *eventCallback = callbackMap[indexObject];
82+
83+ // If index is in range, execute and remove it.
84+ // If not, requests are in the future. Update the index.
85+ [callbackMap removeObjectForKey: indexObject];
86+ if (index >= requests.count ) {
87+ index -= requests.count ;
88+ updatedCallbackMap[@(index)] = eventCallback;
89+ } else if (eventCallback.responseBlock ) {
90+ activeResponseMap[indexObject] = [eventCallback.responseBlock copy ];
91+ }
8592 }
93+ [callbackMap addEntriesFromDictionary: updatedCallbackMap];
94+
95+ // Execute responses afterwards to prevent index collision.
96+ [activeResponseMap enumerateKeysAndObjectsUsingBlock: ^(NSNumber *indexObject, LPNetworkResponseBlock responseBlock, BOOL *stop) {
97+ NSInteger index = [indexObject integerValue ];
98+ id response = [LPResponse getResponseAt: index fromDictionary: responses];
99+ responseBlock (operation, response);
100+ }];
101+ [[LPCountAggregator sharedAggregator ] incrementCount: @" invoke_success_callbacks_on_responses" ];
86102 }
87- [callbackMap addEntriesFromDictionary: updatedCallbackMap];
88-
89- // Execute responses afterwards to prevent index collision.
90- [activeResponseMap enumerateKeysAndObjectsUsingBlock: ^(NSNumber *indexObject, LPNetworkResponseBlock responseBlock, BOOL *stop) {
91- NSInteger index = [indexObject integerValue ];
92- id response = [LPResponse getResponseAt: index fromDictionary: responses];
93- responseBlock (operation, response);
94- }];
95- [[LPCountAggregator sharedAggregator ] incrementCount: @" invoke_success_callbacks_on_responses" ];
96103}
97104
98105+ (void )invokeErrorCallbacksOnResponses : (id )responses
99106{
100- // Handle errors that don't return an HTTP error code.
101- NSMutableDictionary *callbackMap = [LPEventCallbackManager eventCallbackMap ];
102- for (NSUInteger i = 0 ; i < [LPResponse numResponsesInDictionary: responses]; i++) {
103- NSDictionary *response = [LPResponse getResponseAt: i fromDictionary: responses];
104- if ([LPResponse isResponseSuccess: response]) {
105- continue ;
106- }
107-
108- NSString *errorMessage = @" API error" ;
109- NSString *responseError = [LPResponse getResponseError: response];
110- if (responseError) {
111- errorMessage = [NSString stringWithFormat: @" API error: %@ " , errorMessage];
112- }
113- NSLog (@" Leanplum: %@ " , errorMessage);
114-
115- LPEventCallback *callback = callbackMap[@(i)];
116- if (callback) {
117- [callbackMap removeObjectForKey: @(i)];
118- NSError *error = [NSError errorWithDomain: @" Leanplum" code: 2
119- userInfo: @{NSLocalizedDescriptionKey : errorMessage}];
120- [callback invokeError: error];
107+ @synchronized ([LPEventCallbackManager eventCallbackMap ])
108+ {
109+ // Handle errors that don't return an HTTP error code.
110+ NSMutableDictionary *callbackMap = [LPEventCallbackManager eventCallbackMap ];
111+ for (NSUInteger i = 0 ; i < [LPResponse numResponsesInDictionary: responses]; i++) {
112+ NSDictionary *response = [LPResponse getResponseAt: i fromDictionary: responses];
113+ if ([LPResponse isResponseSuccess: response]) {
114+ continue ;
115+ }
116+
117+ NSString *errorMessage = @" API error" ;
118+ NSString *responseError = [LPResponse getResponseError: response];
119+ if (responseError) {
120+ errorMessage = [NSString stringWithFormat: @" API error: %@ " , errorMessage];
121+ }
122+ NSLog (@" Leanplum: %@ " , errorMessage);
123+
124+ LPEventCallback *callback = callbackMap[@(i)];
125+ if (callback) {
126+ [callbackMap removeObjectForKey: @(i)];
127+ NSError *error = [NSError errorWithDomain: @" Leanplum" code: 2
128+ userInfo: @{NSLocalizedDescriptionKey : errorMessage}];
129+ [callback invokeError: error];
130+ }
121131 }
132+ [[LPCountAggregator sharedAggregator ] incrementCount: @" invoke_error_callbacks_on_responses" ];
122133 }
123- [[LPCountAggregator sharedAggregator ] incrementCount: @" invoke_error_callbacks_on_responses" ];
124134}
125135
126136+ (void )invokeErrorCallbacksWithError : (NSError *)error
127137{
128- NSMutableDictionary *callbackMap = [LPEventCallbackManager eventCallbackMap ];
129- for (LPEventCallback *callback in callbackMap.allValues ) {
130- [callback invokeError: error];
138+ @synchronized ([LPEventCallbackManager eventCallbackMap ])
139+ {
140+ NSMutableDictionary *callbackMap = [LPEventCallbackManager eventCallbackMap ];
141+ for (LPEventCallback *callback in callbackMap.allValues ) {
142+ [callback invokeError: error];
143+ }
144+ [callbackMap removeAllObjects ];
131145 }
132- [callbackMap removeAllObjects ];
133146}
134147
135148@end
0 commit comments