aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/objective-c/GRPCClient/GRPCCall.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/objective-c/GRPCClient/GRPCCall.m')
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.m31
1 files changed, 22 insertions, 9 deletions
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index 92084d9d4f..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
@@ -84,6 +84,7 @@
id<GRXWriter> _requestWriter;
NSMutableDictionary *_requestMetadata;
+ NSMutableDictionary *_responseMetadata;
}
@synthesize state = _state;
@@ -120,6 +121,7 @@
_requestWriter = requestWriter;
_requestMetadata = [NSMutableDictionary dictionary];
+ _responseMetadata = [NSMutableDictionary dictionary];
}
return self;
}
@@ -134,6 +136,10 @@
_requestMetadata = [NSMutableDictionary dictionaryWithDictionary:requestMetadata];
}
+- (NSDictionary *)responseMetadata {
+ return _responseMetadata;
+}
+
#pragma mark Finish
- (void)finishWithError:(NSError *)errorOrNil {
@@ -291,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]]];
@@ -301,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];