Revert format changes in related files

pull/8561/head
Muxi Yan 8 years ago
parent 2c88b4616a
commit 61274cac90
  1. 201
      src/objective-c/GRPCClient/GRPCCall.m
  2. 15
      src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
  3. 68
      src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
  4. 81
      src/objective-c/GRPCClient/private/GRPCHost.m
  5. 368
      src/objective-c/tests/Tests.xcodeproj/project.pbxproj

@ -33,9 +33,9 @@
#import "GRPCCall.h" #import "GRPCCall.h"
#import <RxLibrary/GRXConcurrentWriteable.h>
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/support/time.h> #include <grpc/support/time.h>
#import <RxLibrary/GRXConcurrentWriteable.h>
#import "private/GRPCConnectivityMonitor.h" #import "private/GRPCConnectivityMonitor.h"
#import "private/GRPCHost.h" #import "private/GRPCHost.h"
@ -45,11 +45,11 @@
#import "private/NSDictionary+GRPC.h" #import "private/NSDictionary+GRPC.h"
#import "private/NSError+GRPC.h" #import "private/NSError+GRPC.h"
NSString *const kGRPCHeadersKey = @"io.grpc.HeadersKey"; NSString * const kGRPCHeadersKey = @"io.grpc.HeadersKey";
NSString *const kGRPCTrailersKey = @"io.grpc.TrailersKey"; NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
static NSMutableDictionary *callFlags; static NSMutableDictionary *callFlags;
@interface GRPCCall ()<GRXWriteable> @interface GRPCCall () <GRXWriteable>
// Make them read-write. // Make them read-write.
@property(atomic, strong) NSDictionary *responseHeaders; @property(atomic, strong) NSDictionary *responseHeaders;
@property(atomic, strong) NSDictionary *responseTrailers; @property(atomic, strong) NSDictionary *responseTrailers;
@ -85,21 +85,17 @@ static NSMutableDictionary *callFlags;
// correct ordering. // correct ordering.
GRXConcurrentWriteable *_responseWriteable; GRXConcurrentWriteable *_responseWriteable;
// The network thread wants the requestWriter to resume (when the server is // The network thread wants the requestWriter to resume (when the server is ready for more input),
// ready for more input), or to stop (on errors), concurrently with user // or to stop (on errors), concurrently with user threads that want to start it, pause it or stop
// threads that want to start it, pause it or stop it. Because a writer isn't // it. Because a writer isn't thread-safe, we'll synchronize those operations on it.
// thread-safe, we'll synchronize those operations on it. // We don't use a dispatch queue for that purpose, because the writer can call writeValue: or
// We don't use a dispatch queue for that purpose, because the writer can call // writesFinishedWithError: on this GRPCCall as part of those operations. We want to be able to
// writeValue: or writesFinishedWithError: on this GRPCCall as part of those // pause the writer immediately on writeValue:, so we need our locking to be recursive.
// operations. We want to be able to pause the writer immediately on
// writeValue:, so we need our locking to be recursive.
GRXWriter *_requestWriter; GRXWriter *_requestWriter;
// To create a retain cycle when a call is started, up until it finishes. See // To create a retain cycle when a call is started, up until it finishes. See
// |startWithWriteable:| and |finishWithError:|. This saves users from having // |startWithWriteable:| and |finishWithError:|. This saves users from having to retain a
// to retain a // reference to the call object if all they're interested in is the handler being executed when
// reference to the call object if all they're interested in is the handler
// being executed when
// the response arrives. // the response arrives.
GRPCCall *_retainSelf; GRPCCall *_retainSelf;
@ -108,16 +104,13 @@ static NSMutableDictionary *callFlags;
@synthesize state = _state; @synthesize state = _state;
// TODO(jcanizales): If grpc_init is idempotent, this should be changed from // TODO(jcanizales): If grpc_init is idempotent, this should be changed from load to initialize.
// load to initialize.
+ (void)load { + (void)load {
grpc_init(); grpc_init();
callFlags = [NSMutableDictionary dictionary]; callFlags = [NSMutableDictionary dictionary];
} }
+ (void)setCallSafety:(GRPCCallSafety)callSafety + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path {
host:(NSString *)host
path:(NSString *)path {
NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path];
switch (callSafety) { switch (callSafety) {
case GRPCCallSafetyDefault: case GRPCCallSafetyDefault:
@ -148,8 +141,7 @@ static NSMutableDictionary *callFlags;
path:(NSString *)path path:(NSString *)path
requestsWriter:(GRXWriter *)requestWriter { requestsWriter:(GRXWriter *)requestWriter {
if (!host || !path) { if (!host || !path) {
[NSException raise:NSInvalidArgumentException [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."];
format:@"Neither host nor path can be nil."];
} }
if (requestWriter.state != GRXWriterStateNotStarted) { if (requestWriter.state != GRXWriterStateNotStarted) {
[NSException raise:NSInvalidArgumentException [NSException raise:NSInvalidArgumentException
@ -199,10 +191,7 @@ static NSMutableDictionary *callFlags;
- (void)cancel { - (void)cancel {
[self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain [self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
code:GRPCErrorCodeCancelled code:GRPCErrorCodeCancelled
userInfo:@{ userInfo:@{NSLocalizedDescriptionKey: @"Canceled by app"}]];
NSLocalizedDescriptionKey :
@"Canceled by app"
}]];
[self cancelCall]; [self cancelCall];
} }
@ -217,18 +206,15 @@ static NSMutableDictionary *callFlags;
// Only called from the call queue. // Only called from the call queue.
// The handler will be called from the network queue. // The handler will be called from the network queue.
- (void)startReadWithHandler:(void (^)(grpc_byte_buffer *))handler { - (void)startReadWithHandler:(void(^)(grpc_byte_buffer *))handler {
// TODO(jcanizales): Add error handlers for async failures // TODO(jcanizales): Add error handlers for async failures
[_wrappedCall startBatchWithOperations:@[ [[GRPCOpRecvMessage alloc] [_wrappedCall startBatchWithOperations:@[[[GRPCOpRecvMessage alloc] initWithHandler:handler]]];
initWithHandler:handler] ]];
} }
// Called initially from the network queue once response headers are received, // Called initially from the network queue once response headers are received,
// then "recursively" from the responseWriteable queue after each response from // then "recursively" from the responseWriteable queue after each response from the
// the
// server has been written. // server has been written.
// If the call is currently paused, this is a noop. Restarting the call will // If the call is currently paused, this is a noop. Restarting the call will invoke this
// invoke this
// method. // method.
// TODO(jcanizales): Rename to readResponseIfNotPaused. // TODO(jcanizales): Rename to readResponseIfNotPaused.
- (void)startNextRead { - (void)startNextRead {
@ -251,23 +237,15 @@ static NSMutableDictionary *callFlags;
// don't want to throw, because the app shouldn't crash for a behavior // don't want to throw, because the app shouldn't crash for a behavior
// that's on the hands of any server to have. Instead we finish and ask // that's on the hands of any server to have. Instead we finish and ask
// the server to cancel. // the server to cancel.
[weakSelf [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
finishWithError:[NSError code:GRPCErrorCodeResourceExhausted
errorWithDomain:kGRPCErrorDomain userInfo:@{NSLocalizedDescriptionKey: @"Client does not have enough memory to hold the server response."}]];
code:GRPCErrorCodeResourceExhausted
userInfo:@{
NSLocalizedDescriptionKey :
@"Client does not have enough "
@"memory to hold the server "
@"response."
}]];
[weakSelf cancelCall]; [weakSelf cancelCall];
return; return;
} }
[weakWriteable enqueueValue:data [weakWriteable enqueueValue:data completionHandler:^{
completionHandler:^{ [weakSelf startNextRead];
[weakSelf startNextRead]; }];
}];
}]; }];
}); });
} }
@ -276,22 +254,19 @@ static NSMutableDictionary *callFlags;
- (void)sendHeaders:(NSDictionary *)headers { - (void)sendHeaders:(NSDictionary *)headers {
// TODO(jcanizales): Add error handlers for async failures // TODO(jcanizales): Add error handlers for async failures
[_wrappedCall startBatchWithOperations:@[ [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendMetadata alloc] initWithMetadata:headers
[[GRPCOpSendMetadata alloc] flags:[GRPCCall callFlagsForHost:_host path:_path]
initWithMetadata:headers handler:nil]]];
flags:[GRPCCall callFlagsForHost:_host path:_path]
handler:nil]
]];
} }
#pragma mark GRXWriteable implementation #pragma mark GRXWriteable implementation
// Only called from the call queue. The error handler will be called from the // Only called from the call queue. The error handler will be called from the
// network queue if the write didn't succeed. // network queue if the write didn't succeed.
- (void)writeMessage:(NSData *)message - (void)writeMessage:(NSData *)message withErrorHandler:(void (^)())errorHandler {
withErrorHandler:(void (^)())errorHandler {
__weak GRPCCall *weakSelf = self; __weak GRPCCall *weakSelf = self;
void (^resumingHandler)(void) = ^{ void(^resumingHandler)(void) = ^{
// Resume the request writer. // Resume the request writer.
GRPCCall *strongSelf = weakSelf; GRPCCall *strongSelf = weakSelf;
if (strongSelf) { if (strongSelf) {
@ -300,9 +275,8 @@ static NSMutableDictionary *callFlags;
} }
} }
}; };
[_wrappedCall startBatchWithOperations:@[ [[GRPCOpSendMessage alloc] [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendMessage alloc] initWithMessage:message
initWithMessage:message handler:resumingHandler]]
handler:resumingHandler] ]
errorHandler:errorHandler]; errorHandler:errorHandler];
} }
@ -317,20 +291,18 @@ static NSMutableDictionary *callFlags;
__weak GRPCCall *weakSelf = self; __weak GRPCCall *weakSelf = self;
dispatch_async(_callQueue, ^{ dispatch_async(_callQueue, ^{
[weakSelf writeMessage:value [weakSelf writeMessage:value withErrorHandler:^{
withErrorHandler:^{ [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
[weakSelf
finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
code:GRPCErrorCodeInternal code:GRPCErrorCodeInternal
userInfo:nil]]; userInfo:nil]];
}]; }];
}); });
} }
// Only called from the call queue. The error handler will be called from the // 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. // network queue if the requests stream couldn't be closed successfully.
- (void)finishRequestWithErrorHandler:(void (^)())errorHandler { - (void)finishRequestWithErrorHandler:(void (^)())errorHandler {
[_wrappedCall startBatchWithOperations:@[ [[GRPCOpSendClose alloc] init] ] [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendClose alloc] init]]
errorHandler:errorHandler]; errorHandler:errorHandler];
} }
@ -351,19 +323,17 @@ static NSMutableDictionary *callFlags;
#pragma mark Invoke #pragma mark Invoke
// Both handlers will eventually be called, from the network queue. Writes can // Both handlers will eventually be called, from the network queue. Writes can start immediately
// start immediately after this. // after this.
// The first one (headersHandler), when the response headers are received. // The first one (headersHandler), when the response headers are received.
// The second one (completionHandler), whenever the RPC finishes for any reason. // The second one (completionHandler), whenever the RPC finishes for any reason.
- (void)invokeCallWithHeadersHandler:(void (^)(NSDictionary *))headersHandler - (void)invokeCallWithHeadersHandler:(void(^)(NSDictionary *))headersHandler
completionHandler: completionHandler:(void(^)(NSError *, NSDictionary *))completionHandler {
(void (^)(NSError *, NSDictionary *))completionHandler {
// TODO(jcanizales): Add error handlers for async failures // TODO(jcanizales): Add error handlers for async failures
[_wrappedCall startBatchWithOperations:@[ [[GRPCOpRecvMetadata alloc] [_wrappedCall startBatchWithOperations:@[[[GRPCOpRecvMetadata alloc]
initWithHandler:headersHandler] ]]; initWithHandler:headersHandler]]];
[_wrappedCall [_wrappedCall startBatchWithOperations:@[[[GRPCOpRecvStatus alloc]
startBatchWithOperations:@[ [[GRPCOpRecvStatus alloc] initWithHandler:completionHandler]]];
initWithHandler:completionHandler] ]];
} }
- (void)invokeCall { - (void)invokeCall {
@ -371,31 +341,27 @@ static NSMutableDictionary *callFlags;
// Response headers received. // Response headers received.
self.responseHeaders = headers; self.responseHeaders = headers;
[self startNextRead]; [self startNextRead];
} } completionHandler:^(NSError *error, NSDictionary *trailers) {
completionHandler:^(NSError *error, NSDictionary *trailers) { self.responseTrailers = trailers;
self.responseTrailers = trailers;
if (error) {
if (error) { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; if (error.userInfo) {
if (error.userInfo) { [userInfo addEntriesFromDictionary:error.userInfo];
[userInfo addEntriesFromDictionary:error.userInfo]; }
} userInfo[kGRPCTrailersKey] = self.responseTrailers;
userInfo[kGRPCTrailersKey] = self.responseTrailers; // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be
// TODO(jcanizales): The C gRPC library doesn't guarantee that the // called before this one, so an error might end up with trailers but no headers. We
// headers block will be called before this one, so an error might end // shouldn't call finishWithError until ater both blocks are called. It is also when this is
// up with trailers but no headers. We shouldn't call finishWithError // done that we can provide a merged view of response headers and trailers in a thread-safe
// until ater both blocks are called. It is also when this is done // way.
// that we can provide a merged view of response headers and trailers if (self.responseHeaders) {
// in a thread-safe way. userInfo[kGRPCHeadersKey] = self.responseHeaders;
if (self.responseHeaders) { }
userInfo[kGRPCHeadersKey] = self.responseHeaders; error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo];
} }
error = [NSError errorWithDomain:error.domain [self finishWithError:error];
code:error.code }];
userInfo:userInfo];
}
[self finishWithError:error];
}];
// Now that the RPC has been initiated, request writes can start. // Now that the RPC has been initiated, request writes can start.
@synchronized(_requestWriter) { @synchronized(_requestWriter) {
[_requestWriter startWithWriteable:self]; [_requestWriter startWithWriteable:self];
@ -409,16 +375,14 @@ static NSMutableDictionary *callFlags;
_state = GRXWriterStateStarted; _state = GRXWriterStateStarted;
} }
// Create a retain cycle so that this instance lives until the RPC finishes // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled).
// (or is cancelled). This makes RPCs in which the call isn't externally // This makes RPCs in which the call isn't externally retained possible (as long as it is started
// retained possible (as long as it is started before being autoreleased). // before being autoreleased).
// Care is taken not to retain self strongly in any of the blocks used in this // Care is taken not to retain self strongly in any of the blocks used in this implementation, so
// implementation, so that the life of the instance is determined by this // that the life of the instance is determined by this retain cycle.
// retain cycle.
_retainSelf = self; _retainSelf = self;
_responseWriteable = _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable];
[[GRXConcurrentWriteable alloc] initWithWriteable:writeable];
_wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path]; _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host path:_path];
NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?"); NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?");
@ -427,25 +391,19 @@ static NSMutableDictionary *callFlags;
[self invokeCall]; [self invokeCall];
// TODO(jcanizales): Extract this logic somewhere common. // TODO(jcanizales): Extract this logic somewhere common.
NSString *host = NSString *host = [NSURL URLWithString:[@"https://" stringByAppendingString:_host]].host;
[NSURL URLWithString:[@"https://" stringByAppendingString:_host]].host;
if (!host) { if (!host) {
// TODO(jcanizales): Check this on init. // TODO(jcanizales): Check this on init.
[NSException raise:NSInvalidArgumentException [NSException raise:NSInvalidArgumentException format:@"host of %@ is nil", _host];
format:@"host of %@ is nil", _host];
} }
__weak typeof(self) weakSelf = self; __weak typeof(self) weakSelf = self;
_connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:host]; _connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:host];
void (^handler)() = ^{ void (^handler)() = ^{
typeof(self) strongSelf = weakSelf; typeof(self) strongSelf = weakSelf;
if (strongSelf) { if (strongSelf) {
[strongSelf [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
finishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable
code:GRPCErrorCodeUnavailable userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]];
userInfo:@{
NSLocalizedDescriptionKey :
@"Connectivity lost."
}]];
} }
}; };
[_connectivityMonitor handleLossWithHandler:handler [_connectivityMonitor handleLossWithHandler:handler
@ -456,8 +414,7 @@ static NSMutableDictionary *callFlags;
- (void)setState:(GRXWriterState)newState { - (void)setState:(GRXWriterState)newState {
@synchronized(self) { @synchronized(self) {
// Manual transitions are only allowed from the started or paused states. // Manual transitions are only allowed from the started or paused states.
if (_state == GRXWriterStateNotStarted || if (_state == GRXWriterStateNotStarted || _state == GRXWriterStateFinished) {
_state == GRXWriterStateFinished) {
return; return;
} }

@ -45,7 +45,7 @@
*/ */
#define GRPC_XMACRO_ITEM(methodName, FlagName) \ #define GRPC_XMACRO_ITEM(methodName, FlagName) \
@property(nonatomic, readonly) BOOL methodName; @property(nonatomic, readonly) BOOL methodName;
#include "GRPCReachabilityFlagNames.xmacro.h" #include "GRPCReachabilityFlagNames.xmacro.h"
#undef GRPC_XMACRO_ITEM #undef GRPC_XMACRO_ITEM
@ -60,18 +60,17 @@
- (nonnull instancetype)init NS_UNAVAILABLE; - (nonnull instancetype)init NS_UNAVAILABLE;
/** /**
* Queue on which callbacks will be dispatched. Default is the main queue. Set * Queue on which callbacks will be dispatched. Default is the main queue. Set it before calling
* it before calling handleLossWithHandler:. * handleLossWithHandler:.
*/ */
// TODO(jcanizales): Default to a serial background queue instead. // TODO(jcanizales): Default to a serial background queue instead.
@property(nonatomic, strong, null_resettable) dispatch_queue_t queue; @property(nonatomic, strong, null_resettable) dispatch_queue_t queue;
/** /**
* Calls handler every time the connectivity to this instance's host is lost. If * Calls handler every time the connectivity to this instance's host is lost. If this instance is
* this instance is released before that happens, the handler won't be called. * released before that happens, the handler won't be called.
* Only one handler is active at a time, so if this method is called again * Only one handler is active at a time, so if this method is called again before the previous
* before the previous handler has been called, it might never be called at all * handler has been called, it might never be called at all (or yes, if it has already been queued).
* (or yes, if it has already been queued).
*/ */
- (void)handleLossWithHandler:(nonnull void (^)())handler - (void)handleLossWithHandler:(nonnull void (^)())handler
wifiStatusChangeHandler:(nonnull void (^)())wifiStatusChangeHandler; wifiStatusChangeHandler:(nonnull void (^)())wifiStatusChangeHandler;

@ -58,20 +58,19 @@
} }
*/ */
#define GRPC_XMACRO_ITEM(methodName, FlagName) \ #define GRPC_XMACRO_ITEM(methodName, FlagName) \
-(BOOL)methodName { \ - (BOOL)methodName { \
return !!(_flags & kSCNetworkReachabilityFlags##FlagName); \ return !!(_flags & kSCNetworkReachabilityFlags ## FlagName); \
} }
#include "GRPCReachabilityFlagNames.xmacro.h" #include "GRPCReachabilityFlagNames.xmacro.h"
#undef GRPC_XMACRO_ITEM #undef GRPC_XMACRO_ITEM
- (BOOL)isHostReachable { - (BOOL)isHostReachable {
// Note: connectionOnDemand means it'll be reachable only if using the // Note: connectionOnDemand means it'll be reachable only if using the CFSocketStream API or APIs
// CFSocketStream API or APIs on top of it. // on top of it.
// connectionRequired means we can't tell until a connection is attempted // connectionRequired means we can't tell until a connection is attempted (e.g. for VPN on
// (e.g. for VPN on demand). // demand).
return self.reachable && !self.interventionRequired && return self.reachable && !self.interventionRequired && !self.connectionOnDemand;
!self.connectionOnDemand;
} }
- (NSString *)description { - (NSString *)description {
@ -80,9 +79,9 @@
/* /*
* For each flag, add its name to the array if it's ON. Example: * For each flag, add its name to the array if it's ON. Example:
if (self.isCell) { if (self.isCell) {
[activeOptions addObject:@"isCell"]; [activeOptions addObject:@"isCell"];
} }
*/ */
#define GRPC_XMACRO_ITEM(methodName, FlagName) \ #define GRPC_XMACRO_ITEM(methodName, FlagName) \
@ -92,14 +91,12 @@
#include "GRPCReachabilityFlagNames.xmacro.h" #include "GRPCReachabilityFlagNames.xmacro.h"
#undef GRPC_XMACRO_ITEM #undef GRPC_XMACRO_ITEM
return activeOptions.count == 0 return activeOptions.count == 0 ? @"(none)" : [activeOptions componentsJoinedByString:@", "];
? @"(none)"
: [activeOptions componentsJoinedByString:@", "];
} }
- (BOOL)isEqual:(id)object { - (BOOL)isEqual:(id)object {
return [object isKindOfClass:[GRPCReachabilityFlags class]] && return [object isKindOfClass:[GRPCReachabilityFlags class]] &&
_flags == ((GRPCReachabilityFlags *)object)->_flags; _flags == ((GRPCReachabilityFlags *)object)->_flags;
} }
- (NSUInteger)hash { - (NSUInteger)hash {
@ -109,16 +106,15 @@
#pragma mark Connectivity Monitor #pragma mark Connectivity Monitor
// Assumes the third argument is a block that accepts a GRPCReachabilityFlags // Assumes the third argument is a block that accepts a GRPCReachabilityFlags object, and passes the
// object, and passes the received ones to it. // received ones to it.
static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target, static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target,
SCNetworkReachabilityFlags flags, SCNetworkReachabilityFlags flags,
void *info) { void *info) {
#pragma unused(target) #pragma unused (target)
// This can be called many times with the same info. The info is retained by // This can be called many times with the same info. The info is retained by SCNetworkReachability
// SCNetworkReachability while this function is being executed. // while this function is being executed.
void (^handler)(GRPCReachabilityFlags *) = void (^handler)(GRPCReachabilityFlags *) = (__bridge void (^)(GRPCReachabilityFlags *))info;
(__bridge void (^)(GRPCReachabilityFlags *))info;
handler([[GRPCReachabilityFlags alloc] initWithFlags:flags]); handler([[GRPCReachabilityFlags alloc] initWithFlags:flags]);
} }
@ -127,8 +123,7 @@ static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target,
GRPCReachabilityFlags *_previousReachabilityFlags; GRPCReachabilityFlags *_previousReachabilityFlags;
} }
- (nullable instancetype)initWithReachability: - (nullable instancetype)initWithReachability:(nullable SCNetworkReachabilityRef)reachability {
(nullable SCNetworkReachabilityRef)reachability {
if (!reachability) { if (!reachability) {
return nil; return nil;
} }
@ -149,8 +144,7 @@ static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target,
SCNetworkReachabilityRef reachability = SCNetworkReachabilityRef reachability =
SCNetworkReachabilityCreateWithName(NULL, hostName); SCNetworkReachabilityCreateWithName(NULL, hostName);
GRPCConnectivityMonitor *returnValue = GRPCConnectivityMonitor *returnValue = [[self alloc] initWithReachability:reachability];
[[self alloc] initWithReachability:reachability];
if (reachability) { if (reachability) {
CFRelease(reachability); CFRelease(reachability);
} }
@ -176,19 +170,17 @@ static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target,
} }
- (void)startListeningWithHandler:(void (^)(GRPCReachabilityFlags *))handler { - (void)startListeningWithHandler:(void (^)(GRPCReachabilityFlags *))handler {
// Copy to ensure the handler block is in the heap (and so can't be // Copy to ensure the handler block is in the heap (and so can't be deallocated when this method
// deallocated when this method returns). // returns).
void (^copiedHandler)(GRPCReachabilityFlags *) = [handler copy]; void (^copiedHandler)(GRPCReachabilityFlags *) = [handler copy];
SCNetworkReachabilityContext context = { SCNetworkReachabilityContext context = {
.version = 0, .version = 0,
.info = (__bridge void *)copiedHandler, .info = (__bridge void *)copiedHandler,
.retain = CFRetain, .retain = CFRetain,
.release = CFRelease, .release = CFRelease,
}; };
// The following will retain context.info, and release it when the callback is // The following will retain context.info, and release it when the callback is set to NULL.
// set to NULL. SCNetworkReachabilitySetCallback(_reachabilityRef, PassFlagsToContextInfoBlock, &context);
SCNetworkReachabilitySetCallback(_reachabilityRef,
PassFlagsToContextInfoBlock, &context);
SCNetworkReachabilitySetDispatchQueue(_reachabilityRef, _queue); SCNetworkReachabilitySetDispatchQueue(_reachabilityRef, _queue);
} }

@ -33,9 +33,9 @@
#import "GRPCHost.h" #import "GRPCHost.h"
#import <GRPCClient/GRPCCall.h>
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/grpc_security.h> #include <grpc/grpc_security.h>
#import <GRPCClient/GRPCCall.h>
#ifdef GRPC_COMPILE_WITH_CRONET #ifdef GRPC_COMPILE_WITH_CRONET
#import <GRPCClient/GRPCCall+ChannelArg.h> #import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+Cronet.h> #import <GRPCClient/GRPCCall+Cronet.h>
@ -48,8 +48,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
// TODO(jcanizales): Generate the version in a standalone header, from // TODO(jcanizales): Generate the version in a standalone header, from templates. Like
// templates. Like
// templates/src/core/surface/version.c.template . // templates/src/core/surface/version.c.template .
#define GRPC_OBJC_VERSION_STRING @"1.0.0" #define GRPC_OBJC_VERSION_STRING @"1.0.0"
@ -62,8 +61,7 @@ static NSMutableDictionary *kHostCache;
static GRPCConnectivityMonitor *connectivityMonitor = nil; static GRPCConnectivityMonitor *connectivityMonitor = nil;
@implementation GRPCHost { @implementation GRPCHost {
// TODO(mlumish): Investigate whether caching channels with strong links is a // TODO(mlumish): Investigate whether caching channels with strong links is a good idea.
// good idea.
GRPCChannel *_channel; GRPCChannel *_channel;
} }
@ -83,13 +81,11 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
return nil; return nil;
} }
// To provide a default port, we try to interpret the address. If it's just a // To provide a default port, we try to interpret the address. If it's just a host name without
// host name without scheme and without port, we'll use port 443. If it has a // scheme and without port, we'll use port 443. If it has a scheme, we pass it untouched to the C
// scheme, we pass it untouched to the C gRPC library. // gRPC library.
// TODO(jcanizales): Add unit tests for the types of addresses we want to let // TODO(jcanizales): Add unit tests for the types of addresses we want to let pass untouched.
// pass untouched. NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:address]];
NSURL *hostURL =
[NSURL URLWithString:[@"https://" stringByAppendingString:address]];
if (hostURL.host && !hostURL.port) { if (hostURL.host && !hostURL.port) {
address = [hostURL.host stringByAppendingString:@":443"]; address = [hostURL.host stringByAppendingString:@":443"];
} }
@ -99,7 +95,6 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
dispatch_once(&cacheInitialization, ^{ dispatch_once(&cacheInitialization, ^{
kHostCache = [NSMutableDictionary dictionary]; kHostCache = [NSMutableDictionary dictionary];
}); });
@synchronized(kHostCache) { @synchronized(kHostCache) {
GRPCHost *cachedHost = kHostCache[address]; GRPCHost *cachedHost = kHostCache[address];
if (cachedHost) { if (cachedHost) {
@ -137,7 +132,7 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
} }
+ (void)resetAllHostSettings { + (void)resetAllHostSettings {
@synchronized(kHostCache) { @synchronized (kHostCache) {
kHostCache = [NSMutableDictionary dictionary]; kHostCache = [NSMutableDictionary dictionary];
} }
} }
@ -163,19 +158,16 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
static NSError *kDefaultRootsError; static NSError *kDefaultRootsError;
static dispatch_once_t loading; static dispatch_once_t loading;
dispatch_once(&loading, ^{ dispatch_once(&loading, ^{
NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem
// Do not use NSBundle.mainBundle, as it's nil for tests of library // Do not use NSBundle.mainBundle, as it's nil for tests of library projects.
// projects.
NSBundle *bundle = [NSBundle bundleForClass:self.class]; NSBundle *bundle = [NSBundle bundleForClass:self.class];
NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"]; NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"];
NSError *error; NSError *error;
// Files in PEM format can have non-ASCII characters in their comments (e.g. // Files in PEM format can have non-ASCII characters in their comments (e.g. for the name of the
// for the name of the issuer). Load them as UTF8 and produce an ASCII // issuer). Load them as UTF8 and produce an ASCII equivalent.
// equivalent. NSString *contentInUTF8 = [NSString stringWithContentsOfFile:path
NSString *contentInUTF8 = encoding:NSUTF8StringEncoding
[NSString stringWithContentsOfFile:path error:&error];
encoding:NSUTF8StringEncoding
error:&error];
if (contentInUTF8 == nil) { if (contentInUTF8 == nil) {
kDefaultRootsError = error; kDefaultRootsError = error;
return; return;
@ -193,15 +185,11 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
if (errorPtr) { if (errorPtr) {
*errorPtr = kDefaultRootsError; *errorPtr = kDefaultRootsError;
} }
NSAssert(kDefaultRootsASCII, NSAssert(kDefaultRootsASCII, @"Could not read gRPCCertificates.bundle/roots.pem. This file, "
@"Could not read gRPCCertificates.bundle/roots.pem. This file, " "with the root certificates, is needed to establish secure (TLS) connections. "
"with the root certificates, is needed to establish secure " "Because the file is distributed with the gRPC library, this error is usually a sign "
"(TLS) connections. " "that the library wasn't configured correctly for your project. Error: %@",
"Because the file is distributed with the gRPC library, this " kDefaultRootsError);
"error is usually a sign "
"that the library wasn't configured correctly for your "
"project. Error: %@",
kDefaultRootsError);
return NO; return NO;
} }
rootsASCII = kDefaultRootsASCII; rootsASCII = kDefaultRootsASCII;
@ -212,12 +200,10 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL); creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL);
} else { } else {
grpc_ssl_pem_key_cert_pair key_cert_pair; grpc_ssl_pem_key_cert_pair key_cert_pair;
NSData *privateKeyASCII = NSData *privateKeyASCII = [pemPrivateKey dataUsingEncoding:NSASCIIStringEncoding
[pemPrivateKey dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
allowLossyConversion:YES]; NSData *certChainASCII = [pemCertChain dataUsingEncoding:NSASCIIStringEncoding
NSData *certChainASCII = allowLossyConversion:YES];
[pemCertChain dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
key_cert_pair.private_key = privateKeyASCII.bytes; key_cert_pair.private_key = privateKeyASCII.bytes;
key_cert_pair.cert_chain = certChainASCII.bytes; key_cert_pair.cert_chain = certChainASCII.bytes;
creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL); creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL);
@ -237,8 +223,7 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
NSMutableDictionary *args = [NSMutableDictionary dictionary]; NSMutableDictionary *args = [NSMutableDictionary dictionary];
// TODO(jcanizales): Add OS and device information (see // TODO(jcanizales): Add OS and device information (see
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#user-agents // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#user-agents ).
// ).
NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING;
if (_userAgentPrefix) { if (_userAgentPrefix) {
userAgent = [_userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; userAgent = [_userAgentPrefix stringByAppendingFormat:@" %@", userAgent];
@ -252,7 +237,7 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
if (_responseSizeLimitOverride) { if (_responseSizeLimitOverride) {
args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = _responseSizeLimitOverride; args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = _responseSizeLimitOverride;
} }
// Use 10000ms initial backoff time for correct behavior on bad/slow networks // Use 10000ms initial backoff time for correct behavior on bad/slow networks
args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = @10000; args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = @10000;
return args; return args;
} }
@ -266,15 +251,12 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
GRPCChannel *channel; GRPCChannel *channel;
@synchronized(self) { @synchronized(self) {
if (_channelCreds == nil) { if (_channelCreds == nil) {
[self setTLSPEMRootCerts:nil [self setTLSPEMRootCerts:nil withPrivateKey:nil withCertChain:nil error:nil];
withPrivateKey:nil
withCertChain:nil
error:nil];
} }
#ifdef GRPC_COMPILE_WITH_CRONET #ifdef GRPC_COMPILE_WITH_CRONET
if (useCronet) { if (useCronet) {
channel = channel = [GRPCChannel secureCronetChannelWithHost:_address
[GRPCChannel secureCronetChannelWithHost:_address channelArgs:args]; channelArgs:args];
} else } else
#endif #endif
{ {
@ -290,8 +272,7 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
} }
- (NSString *)hostName { - (NSString *)hostName {
// TODO(jcanizales): Default to nil instead of _address when Issue #2635 is // TODO(jcanizales): Default to nil instead of _address when Issue #2635 is clarified.
// clarified.
return _hostNameOverride ?: _address; return _hostNameOverride ?: _address;
} }

@ -367,12 +367,15 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */; buildConfigurationList = 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */;
buildPhases = ( buildPhases = (
19087EB522BF2CB904F217C6 /* 📦 Check Pods Manifest.lock */,
F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */, F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */,
5E8A5DA01D3840B4000F8BC4 /* Sources */, 5E8A5DA01D3840B4000F8BC4 /* Sources */,
5E8A5DA11D3840B4000F8BC4 /* Frameworks */, 5E8A5DA11D3840B4000F8BC4 /* Frameworks */,
5E8A5DA21D3840B4000F8BC4 /* Resources */, 5E8A5DA21D3840B4000F8BC4 /* Resources */,
E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */, E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */,
6DFE9E77CAB5760196D79E0F /* [CP] Copy Pods Resources */, 6DFE9E77CAB5760196D79E0F /* [CP] Copy Pods Resources */,
39F149BCA768141AB2C9605E /* 📦 Embed Pods Frameworks */,
A7FFC1089E80998BD3D8A74A /* 📦 Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -388,12 +391,15 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 5EE84BFB1D4717E40050C6CC /* Build configuration list for PBXNativeTarget "InteropTestsRemoteWithCronet" */; buildConfigurationList = 5EE84BFB1D4717E40050C6CC /* Build configuration list for PBXNativeTarget "InteropTestsRemoteWithCronet" */;
buildPhases = ( buildPhases = (
0F063848BBC170233CB9174A /* 📦 Check Pods Manifest.lock */,
C0F7B1FF6F88CC5FBF362F4C /* [CP] Check Pods Manifest.lock */, C0F7B1FF6F88CC5FBF362F4C /* [CP] Check Pods Manifest.lock */,
5EE84BED1D4717E40050C6CC /* Sources */, 5EE84BED1D4717E40050C6CC /* Sources */,
5EE84BEE1D4717E40050C6CC /* Frameworks */, 5EE84BEE1D4717E40050C6CC /* Frameworks */,
5EE84BEF1D4717E40050C6CC /* Resources */, 5EE84BEF1D4717E40050C6CC /* Resources */,
31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */, 31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */,
DB4D0E73C229F2FF3B364AB3 /* [CP] Copy Pods Resources */, DB4D0E73C229F2FF3B364AB3 /* [CP] Copy Pods Resources */,
80E19E63650C69937C98132E /* 📦 Embed Pods Frameworks */,
77F81F984F9E1A6D1980CE21 /* 📦 Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -409,12 +415,15 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */; buildConfigurationList = 63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */;
buildPhases = ( buildPhases = (
15013B7EA3F1FC5E439C9FE4 /* 📦 Check Pods Manifest.lock */,
914ADDD7106BA9BB8A7E569F /* [CP] Check Pods Manifest.lock */, 914ADDD7106BA9BB8A7E569F /* [CP] Check Pods Manifest.lock */,
63423F401B150A5F006CF63C /* Sources */, 63423F401B150A5F006CF63C /* Sources */,
63423F411B150A5F006CF63C /* Frameworks */, 63423F411B150A5F006CF63C /* Frameworks */,
63423F421B150A5F006CF63C /* Resources */, 63423F421B150A5F006CF63C /* Resources */,
A441F71824DCB9D0CA297748 /* [CP] Copy Pods Resources */, A441F71824DCB9D0CA297748 /* [CP] Copy Pods Resources */,
5F14F59509E10C2852014F9E /* [CP] Embed Pods Frameworks */, 5F14F59509E10C2852014F9E /* [CP] Embed Pods Frameworks */,
23D92EBBC256C129A46F7A84 /* 📦 Embed Pods Frameworks */,
711CEB2D404D3DE6AF548461 /* 📦 Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -430,11 +439,13 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 635697DB1B14FC11007A7283 /* Build configuration list for PBXNativeTarget "Tests" */; buildConfigurationList = 635697DB1B14FC11007A7283 /* Build configuration list for PBXNativeTarget "Tests" */;
buildPhases = ( buildPhases = (
10292E33F3C86516707EEF7B /* 📦 Check Pods Manifest.lock */,
796680C7599CB4ED736DD62A /* [CP] Check Pods Manifest.lock */, 796680C7599CB4ED736DD62A /* [CP] Check Pods Manifest.lock */,
635697C31B14FC11007A7283 /* Sources */, 635697C31B14FC11007A7283 /* Sources */,
635697C41B14FC11007A7283 /* Frameworks */, 635697C41B14FC11007A7283 /* Frameworks */,
635697C51B14FC11007A7283 /* CopyFiles */, 635697C51B14FC11007A7283 /* CopyFiles */,
AEEBFC914CBAEE347382E8C4 /* [CP] Copy Pods Resources */, AEEBFC914CBAEE347382E8C4 /* [CP] Copy Pods Resources */,
03DF64A98174687EB75C8E97 /* 📦 Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -449,12 +460,15 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 63DC841B1BE15179000708E8 /* Build configuration list for PBXNativeTarget "RxLibraryUnitTests" */; buildConfigurationList = 63DC841B1BE15179000708E8 /* Build configuration list for PBXNativeTarget "RxLibraryUnitTests" */;
buildPhases = ( buildPhases = (
B43DE93E4F0303EF4EAEE11D /* 📦 Check Pods Manifest.lock */,
B2986CEEE8CDD4901C97598B /* [CP] Check Pods Manifest.lock */, B2986CEEE8CDD4901C97598B /* [CP] Check Pods Manifest.lock */,
63DC840F1BE15179000708E8 /* Sources */, 63DC840F1BE15179000708E8 /* Sources */,
63DC84101BE15179000708E8 /* Frameworks */, 63DC84101BE15179000708E8 /* Frameworks */,
63DC84111BE15179000708E8 /* Resources */, 63DC84111BE15179000708E8 /* Resources */,
4F5690DC0E6AD6663FE78B8B /* [CP] Embed Pods Frameworks */, 4F5690DC0E6AD6663FE78B8B /* [CP] Embed Pods Frameworks */,
C977426A8727267BBAC7D48E /* [CP] Copy Pods Resources */, C977426A8727267BBAC7D48E /* [CP] Copy Pods Resources */,
32B797E37F2930B455ACC451 /* 📦 Embed Pods Frameworks */,
A27B9173DCE3B597DF3A2DB3 /* 📦 Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -470,12 +484,15 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 63DC842B1BE15267000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsRemote" */; buildConfigurationList = 63DC842B1BE15267000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsRemote" */;
buildPhases = ( buildPhases = (
70A6CC12EA2EE59304D0AAFD /* 📦 Check Pods Manifest.lock */,
4C406327D3907A5E5FBA8AC9 /* [CP] Check Pods Manifest.lock */, 4C406327D3907A5E5FBA8AC9 /* [CP] Check Pods Manifest.lock */,
63DC841F1BE15267000708E8 /* Sources */, 63DC841F1BE15267000708E8 /* Sources */,
63DC84201BE15267000708E8 /* Frameworks */, 63DC84201BE15267000708E8 /* Frameworks */,
63DC84211BE15267000708E8 /* Resources */, 63DC84211BE15267000708E8 /* Resources */,
900B6EDD4D16BE7D765C3885 /* [CP] Embed Pods Frameworks */, 900B6EDD4D16BE7D765C3885 /* [CP] Embed Pods Frameworks */,
C2E09DC4BD239F71160F0CC1 /* [CP] Copy Pods Resources */, C2E09DC4BD239F71160F0CC1 /* [CP] Copy Pods Resources */,
39ADC6D7DCA87D823CF3D846 /* 📦 Embed Pods Frameworks */,
D8308995758FFA86B3729094 /* 📦 Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -491,12 +508,15 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 63DC843C1BE15294000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalSSL" */; buildConfigurationList = 63DC843C1BE15294000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalSSL" */;
buildPhases = ( buildPhases = (
F14FCE3D40412E4FCC9724B2 /* 📦 Check Pods Manifest.lock */,
5C20DCCB71C3991E6FE78C22 /* [CP] Check Pods Manifest.lock */, 5C20DCCB71C3991E6FE78C22 /* [CP] Check Pods Manifest.lock */,
63DC84301BE15294000708E8 /* Sources */, 63DC84301BE15294000708E8 /* Sources */,
63DC84311BE15294000708E8 /* Frameworks */, 63DC84311BE15294000708E8 /* Frameworks */,
63DC84321BE15294000708E8 /* Resources */, 63DC84321BE15294000708E8 /* Resources */,
C591129ACE9F6CC5EE03FCDE /* [CP] Embed Pods Frameworks */, C591129ACE9F6CC5EE03FCDE /* [CP] Embed Pods Frameworks */,
693DD0B453431D64EA24FD66 /* [CP] Copy Pods Resources */, 693DD0B453431D64EA24FD66 /* [CP] Copy Pods Resources */,
38C9DA9978F7CEC5C1C948FD /* 📦 Embed Pods Frameworks */,
F44F7D1F73DABC8DFA879EBB /* 📦 Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -512,12 +532,15 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 63DC844B1BE152B5000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalCleartext" */; buildConfigurationList = 63DC844B1BE152B5000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalCleartext" */;
buildPhases = ( buildPhases = (
47F37D18E60280F28A8963E1 /* 📦 Check Pods Manifest.lock */,
7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */, 7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */,
63DC843F1BE152B5000708E8 /* Sources */, 63DC843F1BE152B5000708E8 /* Sources */,
63DC84401BE152B5000708E8 /* Frameworks */, 63DC84401BE152B5000708E8 /* Frameworks */,
63DC84411BE152B5000708E8 /* Resources */, 63DC84411BE152B5000708E8 /* Resources */,
A8E3AC66DF770B774114A30E /* [CP] Embed Pods Frameworks */, A8E3AC66DF770B774114A30E /* [CP] Embed Pods Frameworks */,
8AD3130D3C58A0FB32FF2A36 /* [CP] Copy Pods Resources */, 8AD3130D3C58A0FB32FF2A36 /* [CP] Copy Pods Resources */,
4FE4AE42DC5C550150618556 /* 📦 Embed Pods Frameworks */,
3139677FA758B7AF69186BC0 /* 📦 Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -643,6 +666,111 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
03DF64A98174687EB75C8E97 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
0F063848BBC170233CB9174A /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
10292E33F3C86516707EEF7B /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
15013B7EA3F1FC5E439C9FE4 /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
19087EB522BF2CB904F217C6 /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
23D92EBBC256C129A46F7A84 /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
3139677FA758B7AF69186BC0 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh\"\n";
showEnvVarsInLog = 0;
};
31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */ = { 31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -658,6 +786,81 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh\"\n"; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
32B797E37F2930B455ACC451 /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
38C9DA9978F7CEC5C1C948FD /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
39ADC6D7DCA87D823CF3D846 /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
39F149BCA768141AB2C9605E /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
47F37D18E60280F28A8963E1 /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
4C406327D3907A5E5FBA8AC9 /* [CP] Check Pods Manifest.lock */ = { 4C406327D3907A5E5FBA8AC9 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -688,6 +891,21 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-frameworks.sh\"\n"; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
4FE4AE42DC5C550150618556 /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
5C20DCCB71C3991E6FE78C22 /* [CP] Check Pods Manifest.lock */ = { 5C20DCCB71C3991E6FE78C22 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -748,6 +966,36 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-resources.sh\"\n"; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-resources.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
70A6CC12EA2EE59304D0AAFD /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
711CEB2D404D3DE6AF548461 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */ = { 7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -763,6 +1011,21 @@
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
77F81F984F9E1A6D1980CE21 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-resources.sh\"\n";
showEnvVarsInLog = 0;
};
796680C7599CB4ED736DD62A /* [CP] Check Pods Manifest.lock */ = { 796680C7599CB4ED736DD62A /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -778,6 +1041,21 @@
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
80E19E63650C69937C98132E /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
8AD3130D3C58A0FB32FF2A36 /* [CP] Copy Pods Resources */ = { 8AD3130D3C58A0FB32FF2A36 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -823,6 +1101,21 @@
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
A27B9173DCE3B597DF3A2DB3 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
A441F71824DCB9D0CA297748 /* [CP] Copy Pods Resources */ = { A441F71824DCB9D0CA297748 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -838,6 +1131,21 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh\"\n"; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
A7FFC1089E80998BD3D8A74A /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
A8E3AC66DF770B774114A30E /* [CP] Embed Pods Frameworks */ = { A8E3AC66DF770B774114A30E /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -883,6 +1191,21 @@
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
B43DE93E4F0303EF4EAEE11D /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
C0F7B1FF6F88CC5FBF362F4C /* [CP] Check Pods Manifest.lock */ = { C0F7B1FF6F88CC5FBF362F4C /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -943,6 +1266,21 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh\"\n"; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
D8308995758FFA86B3729094 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-resources.sh\"\n";
showEnvVarsInLog = 0;
};
DB4D0E73C229F2FF3B364AB3 /* [CP] Copy Pods Resources */ = { DB4D0E73C229F2FF3B364AB3 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -973,6 +1311,36 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n"; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
F14FCE3D40412E4FCC9724B2 /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
F44F7D1F73DABC8DFA879EBB /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n";
showEnvVarsInLog = 0;
};
F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */ = { F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;

Loading…
Cancel
Save