Separate GRPCProtoResponseHandler from GRPCResponseHandler

pull/16190/head
Muxi Yan 6 years ago
parent e69a7cc7f7
commit bf09206496
  1. 6
      src/objective-c/GRPCClient/GRPCCall.h
  2. 4
      src/objective-c/GRPCClient/GRPCCall.m
  3. 37
      src/objective-c/ProtoRPC/ProtoRPC.h
  4. 76
      src/objective-c/ProtoRPC/ProtoRPC.m
  5. 2
      src/objective-c/tests/GRPCClientTests.m
  6. 4
      src/objective-c/tests/InteropTests.m

@ -157,10 +157,10 @@ extern id const kGRPCTrailersKey;
- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata; - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata;
/** /**
* Issued when a message is received from the server. The message may be raw data from the server * Issued when a message is received from the server. The message is the raw data received from the
* (when using \a GRPCCall2 directly) or deserialized proto object (when using \a ProtoRPC). * server, with decompression and without proto deserialization.
*/ */
- (void)receivedMessage:(id)message; - (void)receivedRawMessage:(id)message;
/** /**
* Issued when a call finished. If the call finished successfully, \a error is nil and \a * Issued when a call finished. If the call finished successfully, \a error is nil and \a

@ -236,9 +236,9 @@ const char *kCFStreamVarName = "grpc_cfstream";
- (void)issueMessage:(id)message { - (void)issueMessage:(id)message {
id<GRPCResponseHandler> handler = self->_handler; id<GRPCResponseHandler> handler = self->_handler;
if ([handler respondsToSelector:@selector(receivedMessage:)]) { if ([handler respondsToSelector:@selector(receivedRawMessage:)]) {
dispatch_async(handler.dispatchQueue, ^{ dispatch_async(handler.dispatchQueue, ^{
[handler receivedMessage:message]; [handler receivedRawMessage:message];
}); });
} }
} }

@ -23,6 +23,39 @@
@class GPBMessage; @class GPBMessage;
/** An object can implement this protocol to receive responses from server from a call. */
@protocol GRPCProtoResponseHandler <NSObject>
@optional
/** Issued when initial metadata is received from the server. */
- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata;
/**
* Issued when a message is received from the server. The message is the deserialized proto object.
*/
- (void)receivedProtoMessage:(id)message;
/**
* Issued when a call finished. If the call finished successfully, \a error is nil and \a
* trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error
* is non-nil and contains the corresponding error information, including gRPC error codes and
* error descriptions.
*/
- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error;
@required
/**
* All the responses must be issued to a user-provided dispatch queue. This property specifies the
* dispatch queue to be used for issuing the notifications. A serial queue should be provided if
* the order of responses (initial metadata, message, message, ..., message, trailing metadata)
* needs to be maintained.
*/
@property(atomic, readonly) dispatch_queue_t dispatchQueue;
@end
/** A unary-request RPC call with Protobuf. */ /** A unary-request RPC call with Protobuf. */
@interface GRPCUnaryProtoCall : NSObject @interface GRPCUnaryProtoCall : NSObject
@ -36,7 +69,7 @@
*/ */
- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions
message:(GPBMessage *)message message:(GPBMessage *)message
responseHandler:(id<GRPCResponseHandler>)handler responseHandler:(id<GRPCProtoResponseHandler>)handler
callOptions:(GRPCCallOptions *)callOptions callOptions:(GRPCCallOptions *)callOptions
responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER;
@ -57,7 +90,7 @@
* returned to users by methods of the generated service. * returned to users by methods of the generated service.
*/ */
- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions
responseHandler:(id<GRPCResponseHandler>)handler responseHandler:(id<GRPCProtoResponseHandler>)handler
callOptions:(GRPCCallOptions *)callOptions callOptions:(GRPCCallOptions *)callOptions
responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER;

@ -33,7 +33,7 @@
- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions
message:(GPBMessage *)message message:(GPBMessage *)message
responseHandler:(id<GRPCResponseHandler>)handler responseHandler:(id<GRPCProtoResponseHandler>)handler
callOptions:(GRPCCallOptions *)callOptions callOptions:(GRPCCallOptions *)callOptions
responseClass:(Class)responseClass { responseClass:(Class)responseClass {
if ((self = [super init])) { if ((self = [super init])) {
@ -60,7 +60,7 @@
@implementation GRPCStreamingProtoCall { @implementation GRPCStreamingProtoCall {
GRPCRequestOptions *_requestOptions; GRPCRequestOptions *_requestOptions;
id<GRPCResponseHandler> _handler; id<GRPCProtoResponseHandler> _handler;
GRPCCallOptions *_callOptions; GRPCCallOptions *_callOptions;
Class _responseClass; Class _responseClass;
@ -69,7 +69,7 @@
} }
- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions
responseHandler:(id<GRPCResponseHandler>)handler responseHandler:(id<GRPCProtoResponseHandler>)handler
callOptions:(GRPCCallOptions *)callOptions callOptions:(GRPCCallOptions *)callOptions
responseClass:(Class)responseClass { responseClass:(Class)responseClass {
if ((self = [super init])) { if ((self = [super init])) {
@ -98,16 +98,18 @@
_call = nil; _call = nil;
} }
if (_handler) { if (_handler) {
id<GRPCResponseHandler> handler = _handler; id<GRPCProtoResponseHandler> handler = _handler;
dispatch_async(handler.dispatchQueue, ^{ if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) {
[handler closedWithTrailingMetadata:nil dispatch_async(handler.dispatchQueue, ^{
error:[NSError errorWithDomain:kGRPCErrorDomain [handler closedWithTrailingMetadata:nil
code:GRPCErrorCodeCancelled error:[NSError errorWithDomain:kGRPCErrorDomain
userInfo:@{ code:GRPCErrorCodeCancelled
NSLocalizedDescriptionKey : userInfo:@{
@"Canceled by app" NSLocalizedDescriptionKey :
}]]; @"Canceled by app"
}); }]];
});
}
_handler = nil; _handler = nil;
} }
}); });
@ -136,27 +138,33 @@
- (void)receivedInitialMetadata:(NSDictionary *)initialMetadata { - (void)receivedInitialMetadata:(NSDictionary *)initialMetadata {
if (_handler) { if (_handler) {
id<GRPCResponseHandler> handler = _handler; id<GRPCProtoResponseHandler> handler = _handler;
dispatch_async(handler.dispatchQueue, ^{ if ([handler respondsToSelector:@selector(initialMetadata:)]) {
[handler receivedInitialMetadata:initialMetadata]; dispatch_async(handler.dispatchQueue, ^{
}); [handler receivedInitialMetadata:initialMetadata];
});
}
} }
} }
- (void)receivedMessage:(NSData *)message { - (void)receivedRawMessage:(NSData *)message {
if (_handler) { if (_handler) {
id<GRPCResponseHandler> handler = _handler; id<GRPCProtoResponseHandler> handler = _handler;
NSError *error = nil; NSError *error = nil;
id parsed = [_responseClass parseFromData:message error:&error]; id parsed = [_responseClass parseFromData:message error:&error];
if (parsed) { if (parsed) {
dispatch_async(handler.dispatchQueue, ^{ if ([handler respondsToSelector:@selector(receivedProtoMessage:)]) {
[handler receivedMessage:parsed]; dispatch_async(handler.dispatchQueue, ^{
}); [handler receivedProtoMessage:parsed];
});
}
} else { } else {
dispatch_async(handler.dispatchQueue, ^{ if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) {
[handler closedWithTrailingMetadata:nil error:error]; dispatch_async(handler.dispatchQueue, ^{
}); [handler closedWithTrailingMetadata:nil error:error];
handler = nil; });
}
_handler = nil;
[_call cancel]; [_call cancel];
_call = nil; _call = nil;
} }
@ -165,16 +173,16 @@
- (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - (void)closedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
if (_handler) { if (_handler) {
id<GRPCResponseHandler> handler = _handler; id<GRPCProtoResponseHandler> handler = _handler;
dispatch_async(handler.dispatchQueue, ^{ if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) {
[handler closedWithTrailingMetadata:trailingMetadata error:error]; dispatch_async(handler.dispatchQueue, ^{
}); [handler closedWithTrailingMetadata:trailingMetadata error:error];
});
}
_handler = nil; _handler = nil;
} }
if (_call) { [_call cancel];
[_call cancel]; _call = nil;
_call = nil;
}
} }
- (dispatch_queue_t)dispatchQueue { - (dispatch_queue_t)dispatchQueue {

@ -120,7 +120,7 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
} }
} }
- (void)receivedMessage:(id)message { - (void)receivedProtoMessage:(id)message {
if (_messageCallback) { if (_messageCallback) {
_messageCallback(message); _messageCallback(message);
} }

@ -75,7 +75,7 @@ BOOL isRemoteInteropTest(NSString *host) {
} }
// Convenience class to use blocks as callbacks // Convenience class to use blocks as callbacks
@interface InteropTestsBlockCallbacks : NSObject<GRPCResponseHandler> @interface InteropTestsBlockCallbacks : NSObject<GRPCProtoResponseHandler>
- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
messageCallback:(void (^)(id))messageCallback messageCallback:(void (^)(id))messageCallback
@ -108,7 +108,7 @@ BOOL isRemoteInteropTest(NSString *host) {
} }
} }
- (void)receivedMessage:(id)message { - (void)receivedProtoMessage:(id)message {
if (_messageCallback) { if (_messageCallback) {
_messageCallback(message); _messageCallback(message);
} }

Loading…
Cancel
Save