diff options
Diffstat (limited to 'src/objective-c/GRPCClient/GRPCCall.m')
-rw-r--r-- | src/objective-c/GRPCClient/GRPCCall.m | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index a4a0ddb324..279ef935d5 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -46,9 +46,9 @@ #import "private/NSDictionary+GRPC.h" #import "private/NSError+GRPC.h" +NSString * const kGRPCStatusMetadataKey = @"io.grpc.StatusMetadataKey"; + @interface GRPCCall () <GRXWriteable> -// Makes it readwrite. -@property(atomic, strong) NSDictionary *responseMetadata; @end // The following methods of a C gRPC call object aren't reentrant, and thus @@ -82,6 +82,9 @@ // correct ordering. GRPCDelegateWrapper *_responseWriteable; id<GRXWriter> _requestWriter; + + NSMutableDictionary *_requestMetadata; + NSMutableDictionary *_responseMetadata; } @synthesize state = _state; @@ -116,10 +119,27 @@ _callQueue = dispatch_queue_create("org.grpc.call", NULL); _requestWriter = requestWriter; + + _requestMetadata = [NSMutableDictionary dictionary]; + _responseMetadata = [NSMutableDictionary dictionary]; } return self; } +#pragma mark Metadata + +- (NSMutableDictionary *)requestMetadata { + return _requestMetadata; +} + +- (void)setRequestMetadata:(NSDictionary *)requestMetadata { + _requestMetadata = [NSMutableDictionary dictionaryWithDictionary:requestMetadata]; +} + +- (NSDictionary *)responseMetadata { + return _responseMetadata; +} + #pragma mark Finish - (void)finishWithError:(NSError *)errorOrNil { @@ -277,7 +297,7 @@ // The first one (metadataHandler), when the response headers are received. // The second one (completionHandler), whenever the RPC finishes for any reason. - (void)invokeCallWithMetadataHandler:(void(^)(NSDictionary *))metadataHandler - completionHandler:(void(^)(NSError *))completionHandler { + completionHandler:(void(^)(NSError *, NSDictionary *))completionHandler { // TODO(jcanizales): Add error handlers for async failures [_wrappedCall startBatchWithOperations:@[[[GRPCOpRecvMetadata alloc] initWithHandler:metadataHandler]]]; @@ -287,16 +307,23 @@ - (void)invokeCall { __weak GRPCCall *weakSelf = self; - [self invokeCallWithMetadataHandler:^(NSDictionary *metadata) { - // Response metadata received. + [self invokeCallWithMetadataHandler:^(NSDictionary *headers) { + // Response headers received. GRPCCall *strongSelf = weakSelf; if (strongSelf) { - strongSelf.responseMetadata = metadata; + [strongSelf->_responseMetadata addEntriesFromDictionary:headers]; [strongSelf startNextRead]; } - } completionHandler:^(NSError *error) { - // TODO(jcanizales): Merge HTTP2 trailers into response metadata. - [weakSelf finishWithError:error]; + } completionHandler:^(NSError *error, NSDictionary *trailers) { + GRPCCall *strongSelf = weakSelf; + if (strongSelf) { + [strongSelf->_responseMetadata addEntriesFromDictionary:trailers]; + + NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:error.userInfo]; + userInfo[kGRPCStatusMetadataKey] = strongSelf->_responseMetadata; + error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; + [strongSelf finishWithError:error]; + } }]; // Now that the RPC has been initiated, request writes can start. [_requestWriter startWithWriteable:self]; |