17
17
@implementation AWSRNCognitoCredentials {
18
18
NSMutableDictionary *options;
19
19
AWSCognitoCredentialsProvider *credentialProvider;
20
- NSLock * lock;
21
20
AWSRNHelper *helper;
22
21
}
23
22
24
23
@synthesize bridge = _bridge;
24
+ @synthesize methodQueue = _methodQueue;
25
25
26
26
typedef void (^ Block)(id , int );
27
27
@@ -33,6 +33,8 @@ @implementation AWSRNCognitoCredentials{
33
33
const NSString *EXPIRATION = @" expiration" ;
34
34
const NSString *IDENTITY_ID = @" identity_id" ;
35
35
36
+ static NSMutableDictionary * callbacks;
37
+
36
38
RCT_EXPORT_MODULE (AWSRNCognitoCredentials)
37
39
38
40
-(instancetype )init{
@@ -55,22 +57,35 @@ -(instancetype)init{
55
57
}
56
58
57
59
RCT_EXPORT_METHOD (getCredentialsAsync:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
58
- [[credentialProvider credentials ] continueWithBlock: ^id (AWSTask *task) {
59
- if (task.exception ){
60
- dispatch_async (dispatch_get_main_queue (), ^{
61
- @throw [NSException exceptionWithName: task.exception .name reason: task.exception .reason userInfo: task.exception .userInfo];
62
- });
63
- }
64
- if (task.error ) {
65
- reject ([NSString stringWithFormat: @" %ld " ,task.error.code],task.error .description ,task.error );
66
- }
67
- else {
68
- AWSCredentials *cred = (AWSCredentials*) task.result ;
69
- NSDictionary *dict = @{@" AccessKey" :cred.accessKey ,@" SecretKey" :cred.secretKey ,@" SessionKey" :cred.sessionKey ,@" Expiration" :cred.expiration };
70
- resolve (dict);
71
- }
72
- return nil ;
73
- }];
60
+
61
+ // start a separate thread for this to avoid blocking the component queue, since
62
+ // it will have to comunicate with the javascript in the mean time while trying to get the list of logins
63
+
64
+ NSString * queueName = [NSString stringWithFormat: @" %@ .getCredentialsAsyncQueue" ,
65
+ [NSString stringWithUTF8String: dispatch_queue_get_label (self .methodQueue)]
66
+ ];
67
+ dispatch_queue_t concurrentQueue = dispatch_queue_create ([queueName UTF8String ], DISPATCH_QUEUE_CONCURRENT);
68
+
69
+ dispatch_async (concurrentQueue, ^{
70
+
71
+ [[credentialProvider credentials ] continueWithBlock: ^id (AWSTask *task) {
72
+ if (task.exception ){
73
+ dispatch_async (dispatch_get_main_queue (), ^{
74
+ @throw [NSException exceptionWithName: task.exception .name reason: task.exception .reason userInfo: task.exception .userInfo];
75
+ });
76
+ }
77
+ if (task.error ) {
78
+ reject ([NSString stringWithFormat: @" %ld " ,task.error.code],task.error .description ,task.error );
79
+ }
80
+ else {
81
+ AWSCredentials *cred = (AWSCredentials*) task.result ;
82
+ NSDictionary *dict = @{@" AccessKey" :cred.accessKey ,@" SecretKey" :cred.secretKey ,@" SessionKey" :cred.sessionKey ,@" Expiration" :cred.expiration };
83
+ resolve (dict);
84
+ }
85
+ return nil ;
86
+ }];
87
+
88
+ });
74
89
}
75
90
76
91
RCT_EXPORT_METHOD (getIdentityIDAsync:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
@@ -115,17 +130,17 @@ -(instancetype)init{
115
130
#pragma mark - AWSIdentityProviderManager
116
131
117
132
- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins {
118
- if (!lock){
119
- lock = [[NSLock alloc ]init];
120
- }
121
133
return [[AWSTask taskWithResult: nil ] continueWithSuccessBlock: ^id _Nullable (AWSTask * _Nonnull task) {
122
134
__block NSArray * arr;
123
- [self sendMessage: [[NSMutableDictionary alloc ]init] toChannel: @" LoginsRequestedEvent" withCallback: ^(NSArray * response){
135
+
136
+ dispatch_semaphore_t sendMessageSemaphore = dispatch_semaphore_create (0 );
137
+
138
+ [self sendMessage: [[NSMutableDictionary alloc ]init] toChannel: @" LoginsRequestedEvent" semaphore: sendMessageSemaphore withCallback: ^(NSArray * response) {
124
139
arr = response;
125
- [lock unlock ];
126
140
}];
127
- [lock lock ];
128
- [lock unlock ];
141
+
142
+ dispatch_semaphore_wait (sendMessageSemaphore, DISPATCH_TIME_FOREVER);
143
+
129
144
if (![[arr objectAtIndex: 0 ]isKindOfClass:[NSDictionary class ]]){
130
145
return [[NSDictionary alloc ]init];
131
146
}
@@ -143,20 +158,50 @@ -(void)identityDidChange:(NSNotification*)notification {
143
158
NSMutableDictionary *dict = [[NSMutableDictionary alloc ]init];
144
159
[dict setValue: [notification.userInfo valueForKey: AWSCognitoNotificationPreviousId] forKey: @" Previous" ];
145
160
[dict setValue: [notification.userInfo valueForKey: AWSCognitoNotificationNewId] forKey: @" Current" ];
146
- [self sendMessage: dict toChannel: @" IdentityChange" withCallback: nil ];
161
+ [self sendMessage: dict toChannel: @" IdentityChange" ];
147
162
}
148
163
149
- -(void )sendMessage : (NSMutableDictionary *)info toChannel : (NSString *)channel withCallback : (RCTResponseSenderBlock)callback {
150
- if ([channel isEqualToString: @" LoginsRequestedEvent" ]){
151
- [lock lock ];
152
- [info setValue: callback forKey: @" ReturnInfo" ];
164
+
165
+ RCT_EXPORT_METHOD (sendCallbackResponse:(NSString *)callbackId response:(NSArray *)response){
166
+ NSDictionary * callbackInfo = [callbacks objectForKey: callbackId];
167
+ if (callbackInfo) {
168
+ RCTResponseSenderBlock callback = callbackInfo[@" callback" ];
169
+ dispatch_semaphore_t semaphore = callbackInfo[@" semaphore" ];
170
+ [callbacks removeObjectForKey: callbackId];
171
+
172
+ callback (response);
173
+ dispatch_semaphore_signal (semaphore);
174
+ }
175
+ else {
176
+ NSLog (@" WARN callback id not found!" );
153
177
}
178
+ }
179
+
180
+ -(NSString *) registerCallBack : (RCTResponseSenderBlock)callback semaphore : (dispatch_semaphore_t )semaphore {
181
+ if (!callbacks){
182
+ callbacks = [@{} mutableCopy];
183
+ }
184
+ NSString * callbackId = [[NSUUID UUID ] UUIDString ];
185
+ callbacks[callbackId] = @{
186
+ @" callback" : callback ? callback : (^(NSArray *response) { }),
187
+ @" semaphore" :semaphore
188
+ };
189
+ return callbackId;
190
+ }
191
+
192
+ -(void )sendMessage : (NSMutableDictionary *)info toChannel : (NSString *)channel {
154
193
[self .bridge.eventDispatcher
155
194
sendAppEventWithName: channel
156
195
body: [info copy ]
157
196
];
158
197
}
159
198
199
+ -(void )sendMessage : (NSMutableDictionary *)info toChannel : (NSString *)channel semaphore : (dispatch_semaphore_t )semaphore withCallback : (RCTResponseSenderBlock)callback {
200
+ NSString * callbackId = [self registerCallBack: callback semaphore: semaphore];
201
+ [info setValue: callbackId forKey: @" callbackId" ];
202
+ [self sendMessage: info toChannel: channel];
203
+ }
204
+
160
205
-(NSMutableDictionary *)setLogins : (NSMutableDictionary *)reactLogins {
161
206
NSMutableDictionary *logins = [[NSMutableDictionary alloc ]init];
162
207
for (NSString * key in reactLogins){
@@ -186,7 +231,4 @@ -(NSMutableDictionary*)setLogins:(NSMutableDictionary*)reactLogins{
186
231
return logins;
187
232
}
188
233
189
-
190
-
191
-
192
234
@end
0 commit comments