Migrated Objective C library to C batch API

pull/1363/head
murgatroid99 10 years ago
parent ea67c96a99
commit 30b7d4e62e
  1. 109
      src/objective-c/GRPCClient/GRPCCall.m
  2. 4
      src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
  3. 27
      src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
  4. 51
      src/objective-c/GRPCClient/private/GRPCWrappedCall.h
  5. 193
      src/objective-c/GRPCClient/private/GRPCWrappedCall.m
  6. 3
      src/objective-c/GRPCClient/private/NSData+GRPC.m
  7. 4
      src/objective-c/GRPCClient/private/NSDictionary+GRPC.h
  8. 23
      src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
  9. 10
      src/objective-c/GRPCClient/private/NSError+GRPC.h
  10. 39
      src/objective-c/examples/Sample/Podfile.lock
  11. 39
      src/objective-c/examples/Sample/Pods/Manifest.lock
  12. 28861
      src/objective-c/examples/Sample/Pods/Pods.xcodeproj/project.pbxproj

@ -41,6 +41,7 @@
#import "private/GRPCCompletionQueue.h"
#import "private/GRPCDelegateWrapper.h"
#import "private/GRPCMethodName+HTTP2Encoding.h"
#import "GRPCWrappedCall.h"
#import "private/NSData+GRPC.h"
#import "private/NSDictionary+GRPC.h"
#import "private/NSError+GRPC.h"
@ -92,7 +93,7 @@ static void AssertNoErrorInCall(grpc_call_error error) {
@implementation GRPCCall {
dispatch_queue_t _callQueue;
grpc_call *_gRPCCall;
GRPCWrappedCall *_wrappedCall;
dispatch_once_t _callAlreadyInvoked;
GRPCChannel *_channel;
@ -129,10 +130,8 @@ static void AssertNoErrorInCall(grpc_call_error error) {
_completionQueue = [GRPCCompletionQueue completionQueue];
_channel = [GRPCChannel channelToHost:host];
_gRPCCall = grpc_channel_create_call_old(_channel.unmanagedChannel,
method.HTTP2Path.UTF8String,
host.UTF8String,
gpr_inf_future);
_wrappedCall = [[GRPCWrappedCall alloc] initWithChannel:_channel method:method.HTTP2Path host:host];
// Serial queue to invoke the non-reentrant methods of the grpc_call object.
_callQueue = dispatch_queue_create("org.grpc.call", NULL);
@ -156,7 +155,7 @@ static void AssertNoErrorInCall(grpc_call_error error) {
- (void)cancelCall {
// Can be called from any thread, any number of times.
AssertNoErrorInCall(grpc_call_cancel(_gRPCCall));
[_wrappedCall cancel];
}
- (void)cancel {
@ -167,9 +166,8 @@ static void AssertNoErrorInCall(grpc_call_error error) {
}
- (void)dealloc {
grpc_call *gRPCCall = _gRPCCall;
dispatch_async(_callQueue, ^{
grpc_call_destroy(gRPCCall);
_wrappedCall = nil;
});
}
@ -177,8 +175,8 @@ static void AssertNoErrorInCall(grpc_call_error error) {
// Only called from the call queue.
// The handler will be called from the network queue.
- (void)startReadWithHandler:(GRPCEventHandler)handler {
AssertNoErrorInCall(grpc_call_start_read_old(_gRPCCall, (__bridge_retained void *)handler));
- (void)startReadWithHandler:(GRPCCompletionHandler)handler {
[_wrappedCall startBatch:@{@(GRPC_OP_RECV_MESSAGE): @YES} handleCompletion:handler];
}
// Called initially from the network queue once response headers are received,
@ -193,14 +191,17 @@ static void AssertNoErrorInCall(grpc_call_error error) {
}
__weak GRPCCall *weakSelf = self;
__weak GRPCDelegateWrapper *weakWriteable = _responseWriteable;
dispatch_async(_callQueue, ^{
[weakSelf startReadWithHandler:^(grpc_event *event) {
if (!event->data.read) {
// No more responses from the server.
[weakSelf startReadWithHandler:^(NSDictionary *event) {
NSData *data = event[[NSNumber numberWithInt:GRPC_OP_RECV_MESSAGE]];
if (data == [NSNull null]) {
data = nil;
}
if (data == nil) {
// No more responses from the server
return;
}
NSData *data = [NSData grpc_dataWithByteBuffer:event->data.read];
if (!data) {
// The app doesn't have enough memory to hold the server response. We
// don't want to throw, because the app shouldn't crash for a behavior
@ -225,35 +226,11 @@ static void AssertNoErrorInCall(grpc_call_error error) {
#pragma mark Send headers
- (void)addHeaderWithName:(NSString *)name binaryValue:(NSData *)value {
grpc_metadata metadata;
// Safe to discard const qualifiers; we're not going to modify the contents.
metadata.key = (char *)name.UTF8String;
metadata.value = (char *)value.bytes;
metadata.value_length = value.length;
grpc_call_add_metadata_old(_gRPCCall, &metadata, 0);
}
- (void)addHeaderWithName:(NSString *)name ASCIIValue:(NSString *)value {
grpc_metadata metadata;
// Safe to discard const qualifiers; we're not going to modify the contents.
metadata.key = (char *)name.UTF8String;
metadata.value = (char *)value.UTF8String;
// The trailing \0 isn't encoded in HTTP2.
metadata.value_length = value.length;
grpc_call_add_metadata_old(_gRPCCall, &metadata, 0);
}
// TODO(jcanizales): Rename to commitHeaders.
- (void)sendHeaders:(NSDictionary *)metadata {
for (NSString *name in metadata) {
id value = metadata[name];
if ([value isKindOfClass:[NSData class]]) {
[self addHeaderWithName:name binaryValue:value];
} else if ([value isKindOfClass:[NSString class]]) {
[self addHeaderWithName:name ASCIIValue:value];
}
if (metadata == nil) {
metadata = @{};
}
[_wrappedCall startBatch:@{@(GRPC_OP_SEND_INITIAL_METADATA): metadata} handleCompletion:^(NSDictionary * dict){}];
}
#pragma mark GRXWriteable implementation
@ -263,10 +240,7 @@ static void AssertNoErrorInCall(grpc_call_error error) {
- (void)writeMessage:(NSData *)message withErrorHandler:(void (^)())errorHandler {
__weak GRPCCall *weakSelf = self;
GRPCEventHandler resumingHandler = ^(grpc_event *event) {
if (event->data.write_accepted != GRPC_OP_OK) {
errorHandler();
}
GRPCCompletionHandler resumingHandler = ^(NSDictionary *event) {
// Resume the request writer (even in the case of error).
// TODO(jcanizales): No need to do it in the case of errors anymore?
GRPCCall *strongSelf = weakSelf;
@ -274,13 +248,7 @@ static void AssertNoErrorInCall(grpc_call_error error) {
strongSelf->_requestWriter.state = GRXWriterStateStarted;
}
};
grpc_byte_buffer *buffer = message.grpc_byteBuffer;
AssertNoErrorInCall(grpc_call_start_write_old(_gRPCCall,
buffer,
(__bridge_retained void *)resumingHandler,
0));
grpc_byte_buffer_destroy(buffer);
[_wrappedCall startBatch:@{@(GRPC_OP_SEND_MESSAGE): message} handleCompletion:resumingHandler];
}
- (void)didReceiveValue:(id)value {
@ -303,12 +271,7 @@ static void AssertNoErrorInCall(grpc_call_error error) {
// Only called from the call queue. The error handler will be called from the
// network queue if the requests stream couldn't be closed successfully.
- (void)finishRequestWithErrorHandler:(void (^)())errorHandler {
GRPCEventHandler handler = ^(grpc_event *event) {
if (event->data.finish_accepted != GRPC_OP_OK) {
errorHandler();
}
};
AssertNoErrorInCall(grpc_call_writes_done_old(_gRPCCall, (__bridge_retained void *)handler));
[_wrappedCall startBatch:@{@(GRPC_OP_SEND_CLOSE_FROM_CLIENT): @YES} handleCompletion:^(NSDictionary *event){}];
}
- (void)didFinishWithError:(NSError *)errorOrNil {
@ -332,32 +295,28 @@ static void AssertNoErrorInCall(grpc_call_error error) {
// after this.
// The first one (metadataHandler), when the response headers are received.
// The second one (completionHandler), whenever the RPC finishes for any reason.
- (void)invokeCallWithMetadataHandler:(GRPCEventHandler)metadataHandler
completionHandler:(GRPCEventHandler)completionHandler {
AssertNoErrorInCall(grpc_call_invoke_old(_gRPCCall,
_completionQueue.unmanagedQueue,
(__bridge_retained void *)metadataHandler,
(__bridge_retained void *)completionHandler,
0));
- (void)invokeCallWithMetadataHandler:(GRPCCompletionHandler)metadataHandler
completionHandler:(GRPCCompletionHandler)completionHandler {
[_wrappedCall startBatch:@{@(GRPC_OP_RECV_INITIAL_METADATA): @YES} handleCompletion:metadataHandler];
[_wrappedCall startBatch:@{@(GRPC_OP_RECV_STATUS_ON_CLIENT): @YES} handleCompletion:completionHandler];
}
- (void)invokeCall {
__weak GRPCCall *weakSelf = self;
[self invokeCallWithMetadataHandler:^(grpc_event *event) {
[self invokeCallWithMetadataHandler:^(NSDictionary *event) {
// Response metadata received.
// TODO(jcanizales): Name the type of event->data.client_metadata_read
// in the C library so one can actually pass the object to a method.
grpc_metadata *entries = event->data.client_metadata_read.elements;
size_t count = event->data.client_metadata_read.count;
GRPCCall *strongSelf = weakSelf;
if (strongSelf) {
strongSelf.responseMetadata = [NSDictionary grpc_dictionaryFromMetadata:entries
count:count];
strongSelf.responseMetadata = event[@(GRPC_OP_RECV_INITIAL_METADATA)];
[strongSelf startNextRead];
}
} completionHandler:^(grpc_event *event) {
} completionHandler:^(NSDictionary *event) {
// TODO(jcanizales): Merge HTTP2 trailers into response metadata.
[weakSelf finishWithError:[NSError grpc_errorFromStatus:&event->data.finished]];
id error = event[@(GRPC_OP_RECV_STATUS_ON_CLIENT)];
if (error == [NSNull null]) {
error = nil;
}
[weakSelf finishWithError:error];
}];
// Now that the RPC has been initiated, request writes can start.
[_requestWriter startWithWriteable:self];

@ -32,11 +32,11 @@
*/
#import <Foundation/Foundation.h>
#include <grpc/grpc.h>
struct grpc_completion_queue;
struct grpc_event;
typedef void(^GRPCEventHandler)(struct grpc_event *event);
typedef void(^GRPCQueueCompletionHandler)(grpc_op_error error);
// This class lets one more easily use grpc_completion_queue. To use it, pass
// the value of the unmanagedQueue property of an instance of this class to

@ -66,30 +66,17 @@
while (YES) {
// The following call blocks until an event is available.
grpc_event *event = grpc_completion_queue_next(unmanagedQueue, gpr_inf_future);
GRPCQueueCompletionHandler handler;
switch (event->type) {
case GRPC_WRITE_ACCEPTED:
case GRPC_FINISH_ACCEPTED:
case GRPC_CLIENT_METADATA_READ:
case GRPC_READ:
case GRPC_FINISHED:
if (event->tag) {
GRPCEventHandler handler = (__bridge_transfer GRPCEventHandler) event->tag;
handler(event);
}
grpc_event_finish(event);
continue;
case GRPC_OP_COMPLETE:
handler = (__bridge_transfer GRPCQueueCompletionHandler)event->tag;
handler(event->data.op_complete);
break;
case GRPC_QUEUE_SHUTDOWN:
grpc_completion_queue_destroy(unmanagedQueue);
grpc_event_finish(event);
return;
case GRPC_SERVER_RPC_NEW:
NSAssert(NO, @"C gRPC library produced a server-only event.");
continue;
default:
[NSException raise:@"Unrecognized completion type" format:@""];
}
// This means the C gRPC library produced an event that wasn't known
// when this library was written. To preserve evolvability, ignore the
// unknown event on release builds.
NSAssert(NO, @"C gRPC library produced an unknown event.");
};
});
}

@ -0,0 +1,51 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef Pods_GRPCWrappedCall_h
#define Pods_GRPCWrappedCall_h
#import <Foundation/Foundation.h>
#import "GRPCChannel.h"
typedef void(^GRPCCompletionHandler)(NSDictionary *);
@interface GRPCWrappedCall:NSObject;
- (instancetype)initWithChannel:(GRPCChannel *)channel method:(NSString *)method host:(NSString *)host;
- (void)startBatch:(NSDictionary *)ops handleCompletion:(GRPCCompletionHandler)handleCompletion;
- (void)cancel;
@end
#endif

@ -0,0 +1,193 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#import <Foundation/Foundation.h>
#import "GRPCWrappedCall.h"
#import "GRPCCompletionQueue.h"
#import "NSDictionary+GRPC.h"
#import "NSData+GRPC.h"
#import "NSError+GRPC.h"
#include <grpc/grpc.h>
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
@implementation GRPCWrappedCall{
grpc_call *call;
GRPCCompletionQueue *queue;
}
- (instancetype)init {
return [self initWithChannel:nil method:nil host:nil];
}
- (instancetype)initWithChannel:(GRPCChannel *)channel method:(NSString *)method host:(NSString *)host {
if (!channel || !method || !host) {
[NSException raise:NSInvalidArgumentException format:@"channel, method, and host cannot be nil."];
}
if (self = [super init]) {
static dispatch_once_t initialization;
dispatch_once(&initialization, ^{
grpc_init();
});
const char *method_str = [method UTF8String];
const char *host_str = [host UTF8String];
queue = [GRPCCompletionQueue completionQueue];
call = grpc_channel_create_call(channel.unmanagedChannel, queue.unmanagedQueue, method_str, host_str, gpr_inf_future);
if (call == NULL) {
return nil;
}
}
return self;
}
- (void)startBatch:(NSDictionary *)ops handleCompletion:(GRPCCompletionHandler)handleCompletion {
size_t nops = ops.count;
grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op));
size_t index = 0;
NSMutableDictionary * __block opProcessors = [NSMutableDictionary new];
grpc_metadata *send_metadata = NULL;
grpc_metadata_array *recv_initial_metadata;
grpc_metadata_array *recv_trailing_metadata;
grpc_byte_buffer *send_message;
grpc_byte_buffer **recv_message = NULL;
grpc_status_code *status_code;
char **status_details;
size_t *status_details_capacity;
for (id key in ops) {
id (^opBlock)(void);
grpc_op *current = &ops_array[index];
switch ([key intValue]) {
case GRPC_OP_SEND_INITIAL_METADATA:
current->data.send_initial_metadata.count = [ops[key] grpc_toMetadataArray:&send_metadata];
current->data.send_initial_metadata.metadata = send_metadata;
opBlock = ^{
gpr_free(send_metadata);
return @YES;
};
break;
case GRPC_OP_SEND_MESSAGE:
send_message = [ops[key] grpc_byteBuffer];
current->data.send_message = send_message;
opBlock = ^{
grpc_byte_buffer_destroy(send_message);
return @YES;
};
break;
case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
opBlock = ^{
return @YES;
};
break;
case GRPC_OP_RECV_INITIAL_METADATA:
recv_initial_metadata = gpr_malloc(sizeof(grpc_metadata_array));
grpc_metadata_array_init(recv_initial_metadata);
current->data.recv_initial_metadata = recv_initial_metadata;
opBlock = ^{
NSDictionary *metadata = [NSDictionary grpc_dictionaryFromMetadata:recv_initial_metadata->metadata count:recv_initial_metadata->count];
grpc_metadata_array_destroy(recv_initial_metadata);
return metadata;
};
break;
case GRPC_OP_RECV_MESSAGE:
recv_message = gpr_malloc(sizeof(grpc_byte_buffer*));
current->data.recv_message = recv_message;
opBlock = ^{
NSData *data = [NSData grpc_dataWithByteBuffer:*recv_message];
grpc_byte_buffer_destroy(*recv_message);
gpr_free(recv_message);
return data;
};
break;
case GRPC_OP_RECV_STATUS_ON_CLIENT:
status_code = gpr_malloc(sizeof(status_code));
current->data.recv_status_on_client.status = status_code;
status_details = gpr_malloc(sizeof(char*));
*status_details = NULL;
current->data.recv_status_on_client.status_details = status_details;
status_details_capacity = gpr_malloc(sizeof(grpc_status_code));
*status_details_capacity = 0;
current->data.recv_status_on_client.status_details_capacity = status_details_capacity;
recv_trailing_metadata = gpr_malloc(sizeof(grpc_metadata_array));
grpc_metadata_array_init(recv_trailing_metadata);
current->data.recv_status_on_client.trailing_metadata = recv_trailing_metadata;
opBlock = ^{
grpc_status status;
status.status = *status_code;
status.details = *status_details;
status.metadata = recv_trailing_metadata;
gpr_free(status_code);
gpr_free(status_details);
gpr_free(status_details_capacity);
return [NSError grpc_errorFromStatus:&status];
};
break;
case GRPC_OP_SEND_STATUS_FROM_SERVER:
[NSException raise:NSInvalidArgumentException format:@"Not a server: cannot send status"];
default:
[NSException raise:NSInvalidArgumentException format:@"Unrecognized dictionary key"];
}
current->op = [key intValue];
[opProcessors setObject:opBlock forKey:key];
}
grpc_call_error error = grpc_call_start_batch(call, ops_array, nops, (__bridge_retained void *)(^(grpc_op_error error){
if (error != GRPC_OP_OK) {
[NSException raise:@"Operation Exception" format:@"The batch failed with an unknown error"];
}
NSMutableDictionary *result = [NSMutableDictionary new];
for (id key in opProcessors) {
id(^block)(void) = opProcessors[key];
id value = block();
if (value == nil) {
value = [NSNull null];
}
[result setObject:value forKey:key];
}
handleCompletion(result);
}));
if (error != GRPC_CALL_OK) {
[NSException raise:NSInvalidArgumentException format:@"The batch did not start successfully"];
}
}
- (void)cancel {
grpc_call_cancel(call);
}
- (void)dealloc {
grpc_call_destroy(call);
}
@end

@ -59,6 +59,9 @@ static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array, size_t
@implementation NSData (GRPC)
+ (instancetype)grpc_dataWithByteBuffer:(grpc_byte_buffer *)buffer {
if (buffer == NULL) {
return nil;
}
NSUInteger length = grpc_byte_buffer_length(buffer);
char *array = malloc(length * sizeof(*array));
if (!array) {

@ -32,9 +32,9 @@
*/
#import <Foundation/Foundation.h>
struct grpc_metadata;
#include <grpc/grpc.h>
@interface NSDictionary (GRPC)
+ (instancetype)grpc_dictionaryFromMetadata:(struct grpc_metadata *)entries count:(size_t)count;
- (size_t)grpc_toMetadataArray:(grpc_metadata **)metadata;
@end

@ -33,7 +33,8 @@
#import "NSDictionary+GRPC.h"
#include <grpc.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
@implementation NSDictionary (GRPC)
+ (instancetype)grpc_dictionaryFromMetadata:(grpc_metadata *)entries count:(size_t)count {
@ -53,4 +54,24 @@
}
return metadata;
}
- (size_t)grpc_toMetadataArray:(grpc_metadata **)metadata {
size_t count = 0;
size_t capacity = 0;
for (id key in self) {
capacity += [self[key] count];
}
*metadata = gpr_malloc(capacity * sizeof(grpc_metadata));
for (id key in self) {
id value_array = self[key];
for (id value in value_array) {
grpc_metadata *current = &(*metadata)[count];
current->key = [key UTF8String];
current->value = [value UTF8String];
current->value_length = [value length];
count += 1;
}
}
return count;
}
@end

@ -58,14 +58,12 @@ typedef NS_ENUM(NSInteger, GRPCErrorCode) {
// TODO(jcanizales): This is conflating trailing metadata with Status details. Fix it once there's
// a decision on how to codify Status.
#include <grpc/status.h>
struct grpc_metadata;
struct grpc_status {
#include <grpc/grpc.h>
typedef struct grpc_status {
grpc_status_code status;
const char *details;
size_t metadata_count;
struct grpc_metadata *metadata_elements;
};
grpc_metadata_array *metadata;
} grpc_status;
@interface NSError (GRPC)
// Returns nil if the status is OK. Otherwise, a NSError whose code is one of

@ -1,20 +1,35 @@
PODS:
- GRPCClient (0.0.1):
- RxLibrary (~> 0.0)
- RxLibrary (0.0.1)
- gRPC (0.0.1):
- gRPC/C-Core (= 0.0.1)
- gRPC/RxLibrary (= 0.0.1)
- gRPC/C-Core (0.0.1):
- OpenSSL (~> 1.0.200)
- gRPC/RxLibrary (0.0.1)
- OpenSSL (1.0.201)
- ProtocolBuffers (1.9.8)
- RemoteTest (0.0.1):
- ProtocolBuffers (~> 1.9)
- Route_guide (0.0.1):
- ProtocolBuffers (~> 1.9)
DEPENDENCIES:
- GRPCClient (from `../../GRPCClient`)
- RxLibrary (from `../../RxLibrary`)
- gRPC (from `../../../..`)
- RemoteTest (from `RemoteTestClient`)
- Route_guide (from `RouteGuideClient`)
EXTERNAL SOURCES:
GRPCClient:
:path: ../../GRPCClient
RxLibrary:
:path: ../../RxLibrary
gRPC:
:path: ../../../..
RemoteTest:
:path: RemoteTestClient
Route_guide:
:path: RouteGuideClient
SPEC CHECKSUMS:
GRPCClient: 05c58faab99661384178bb7c5f93b60c2bfc89f8
RxLibrary: 70cfcf1573ec16a375b4fe61d976a3188aab9303
gRPC: 70fefb183437c880dbe8f9a477ff0d409e81e390
OpenSSL: 4e990d04b14015c49c800c400b86ae44a4818a5c
ProtocolBuffers: 9a4a171c0c7cc8f21dd29aeca4f9ac775d84a880
RemoteTest: d7bbf2e0646a886ea9502375f0f79e8fe551aa71
Route_guide: a277da8eef182774abb050d7b81109f5878f8652
COCOAPODS: 0.35.0
COCOAPODS: 0.36.4

@ -1,20 +1,35 @@
PODS:
- GRPCClient (0.0.1):
- RxLibrary (~> 0.0)
- RxLibrary (0.0.1)
- gRPC (0.0.1):
- gRPC/C-Core (= 0.0.1)
- gRPC/RxLibrary (= 0.0.1)
- gRPC/C-Core (0.0.1):
- OpenSSL (~> 1.0.200)
- gRPC/RxLibrary (0.0.1)
- OpenSSL (1.0.201)
- ProtocolBuffers (1.9.8)
- RemoteTest (0.0.1):
- ProtocolBuffers (~> 1.9)
- Route_guide (0.0.1):
- ProtocolBuffers (~> 1.9)
DEPENDENCIES:
- GRPCClient (from `../../GRPCClient`)
- RxLibrary (from `../../RxLibrary`)
- gRPC (from `../../../..`)
- RemoteTest (from `RemoteTestClient`)
- Route_guide (from `RouteGuideClient`)
EXTERNAL SOURCES:
GRPCClient:
:path: ../../GRPCClient
RxLibrary:
:path: ../../RxLibrary
gRPC:
:path: ../../../..
RemoteTest:
:path: RemoteTestClient
Route_guide:
:path: RouteGuideClient
SPEC CHECKSUMS:
GRPCClient: 05c58faab99661384178bb7c5f93b60c2bfc89f8
RxLibrary: 70cfcf1573ec16a375b4fe61d976a3188aab9303
gRPC: 70fefb183437c880dbe8f9a477ff0d409e81e390
OpenSSL: 4e990d04b14015c49c800c400b86ae44a4818a5c
ProtocolBuffers: 9a4a171c0c7cc8f21dd29aeca4f9ac775d84a880
RemoteTest: d7bbf2e0646a886ea9502375f0f79e8fe551aa71
Route_guide: a277da8eef182774abb050d7b81109f5878f8652
COCOAPODS: 0.35.0
COCOAPODS: 0.36.4

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save