aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/objective-c/GRPCClient/private
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2016-10-26 21:00:53 -0700
committerGravatar Craig Tiller <ctiller@google.com>2016-10-26 21:00:53 -0700
commit6e080a36515455f2db5b07465abdeacf3e21c3be (patch)
tree0aa4c9e0297a4408206c93d612efe3852c19fa57 /src/objective-c/GRPCClient/private
parentf6f9cf39c677751fb46d42f303a07687e9bfb26a (diff)
parent3d357d901c5228cf8989aed8949b20d32baad77b (diff)
Merge branch 'buffer_pools_for_realsies' into grpc_slice
Diffstat (limited to 'src/objective-c/GRPCClient/private')
-rw-r--r--src/objective-c/GRPCClient/private/GRPCCompletionQueue.h17
-rw-r--r--src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h19
-rw-r--r--src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m98
-rw-r--r--src/objective-c/GRPCClient/private/GRPCHost.m125
-rw-r--r--src/objective-c/GRPCClient/private/GRPCReachabilityFlagNames.xmacro.h2
-rw-r--r--src/objective-c/GRPCClient/private/GRPCRequestHeaders.m41
-rw-r--r--src/objective-c/GRPCClient/private/GRPCWrappedCall.m86
-rw-r--r--src/objective-c/GRPCClient/private/NSError+GRPC.h7
8 files changed, 235 insertions, 160 deletions
diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
index fe3b8f39d1..c0bbf22c74 100644
--- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
+++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
@@ -34,18 +34,19 @@
#import <Foundation/Foundation.h>
#include <grpc/grpc.h>
-typedef void(^GRPCQueueCompletionHandler)(bool success);
+typedef void (^GRPCQueueCompletionHandler)(bool success);
/**
- * 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 |grpc_channel_create_call|. Then for
- * every |grpc_call_*| method that accepts a tag, you can pass a block of type
- * |GRPCQueueCompletionHandler| (remembering to cast it using |__bridge_retained|). The block is
- * guaranteed to eventually be called, by a concurrent queue, and then released. Each such block is
+ * 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
+ * |grpc_channel_create_call|. Then for every |grpc_call_*| method that accepts
+ * a tag, you can pass a block of type |GRPCQueueCompletionHandler| (remembering
+ * to cast it using |__bridge_retained|). The block is guaranteed to eventually
+ * be called, by a concurrent queue, and then released. Each such block is
* passed a |bool| that tells if the operation was successful.
*
- * Release the GRPCCompletionQueue object only after you are not going to pass any more blocks to
- * the |grpc_call| that's using it.
+ * Release the GRPCCompletionQueue object only after you are not going to pass
+ * any more blocks to the |grpc_call| that's using it.
*/
@interface GRPCCompletionQueue : NSObject
@property(nonatomic, readonly) grpc_completion_queue *unmanagedQueue;
diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
index 2fae410331..941b596d2c 100644
--- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
+++ b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
@@ -45,7 +45,7 @@
*/
#define GRPC_XMACRO_ITEM(methodName, FlagName) \
-@property(nonatomic, readonly) BOOL methodName;
+ @property(nonatomic, readonly) BOOL methodName;
#include "GRPCReachabilityFlagNames.xmacro.h"
#undef GRPC_XMACRO_ITEM
@@ -53,7 +53,6 @@
@property(nonatomic, readonly) BOOL isHostReachable;
@end
-
@interface GRPCConnectivityMonitor : NSObject
+ (nullable instancetype)monitorWithHost:(nonnull NSString *)hostName;
@@ -61,17 +60,19 @@
- (nonnull instancetype)init NS_UNAVAILABLE;
/**
- * Queue on which callbacks will be dispatched. Default is the main queue. Set it before calling
- * handleLossWithHandler:.
+ * Queue on which callbacks will be dispatched. Default is the main queue. Set
+ * it before calling handleLossWithHandler:.
*/
// TODO(jcanizales): Default to a serial background queue instead.
@property(nonatomic, strong, null_resettable) dispatch_queue_t queue;
/**
- * Calls handler every time the connectivity to this instance's host is lost. If this instance is
- * 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 before the previous
- * handler has been called, it might never be called at all (or yes, if it has already been queued).
+ * Calls handler every time the connectivity to this instance's host is lost. If
+ * this instance is 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
+ * before the previous handler has been called, it might never be called at all
+ * (or yes, if it has already been queued).
*/
-- (void)handleLossWithHandler:(nonnull void (^)())handler;
+- (void)handleLossWithHandler:(nonnull void (^)())handler
+ wifiStatusChangeHandler:(nonnull void (^)())wifiStatusChangeHandler;
@end
diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
index b4061bd5ef..fec6391d39 100644
--- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
+++ b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
@@ -58,19 +58,20 @@
}
*/
-#define GRPC_XMACRO_ITEM(methodName, FlagName) \
-- (BOOL)methodName { \
- return !!(_flags & kSCNetworkReachabilityFlags ## FlagName); \
-}
+#define GRPC_XMACRO_ITEM(methodName, FlagName) \
+ -(BOOL)methodName { \
+ return !!(_flags & kSCNetworkReachabilityFlags##FlagName); \
+ }
#include "GRPCReachabilityFlagNames.xmacro.h"
#undef GRPC_XMACRO_ITEM
- (BOOL)isHostReachable {
- // Note: connectionOnDemand means it'll be reachable only if using the CFSocketStream API or APIs
- // on top of it.
- // connectionRequired means we can't tell until a connection is attempted (e.g. for VPN on
- // demand).
- return self.reachable && !self.interventionRequired && !self.connectionOnDemand;
+ // Note: connectionOnDemand means it'll be reachable only if using the
+ // CFSocketStream API or APIs on top of it.
+ // connectionRequired means we can't tell until a connection is attempted
+ // (e.g. for VPN on demand).
+ return self.reachable && !self.interventionRequired &&
+ !self.connectionOnDemand;
}
- (NSString *)description {
@@ -79,24 +80,26 @@
/*
* For each flag, add its name to the array if it's ON. Example:
- if (self.isCell) {
- [activeOptions addObject:@"isCell"];
- }
+ if (self.isCell) {
+ [activeOptions addObject:@"isCell"];
+ }
*/
-#define GRPC_XMACRO_ITEM(methodName, FlagName) \
- if (self.methodName) { \
- [activeOptions addObject:@#methodName]; \
- }
-#include "GRPCReachabilityFlagNames.xmacro.h"
-#undef GRPC_XMACRO_ITEM
+ #define GRPC_XMACRO_ITEM(methodName, FlagName) \
+ if (self.methodName) { \
+ [activeOptions addObject:@ #methodName]; \
+ }
+ #include "GRPCReachabilityFlagNames.xmacro.h"
+ #undef GRPC_XMACRO_ITEM
- return activeOptions.count == 0 ? @"(none)" : [activeOptions componentsJoinedByString:@", "];
+ return activeOptions.count == 0
+ ? @"(none)"
+ : [activeOptions componentsJoinedByString:@", "];
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[GRPCReachabilityFlags class]] &&
- _flags == ((GRPCReachabilityFlags *)object)->_flags;
+ _flags == ((GRPCReachabilityFlags *)object)->_flags;
}
- (NSUInteger)hash {
@@ -106,29 +109,33 @@
#pragma mark Connectivity Monitor
-// Assumes the third argument is a block that accepts a GRPCReachabilityFlags object, and passes the
-// received ones to it.
+// Assumes the third argument is a block that accepts a GRPCReachabilityFlags
+// object, and passes the received ones to it.
static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target,
SCNetworkReachabilityFlags flags,
void *info) {
- #pragma unused (target)
- // This can be called many times with the same info. The info is retained by SCNetworkReachability
- // while this function is being executed.
- void (^handler)(GRPCReachabilityFlags *) = (__bridge void (^)(GRPCReachabilityFlags *))info;
+#pragma unused(target)
+ // This can be called many times with the same info. The info is retained by
+ // SCNetworkReachability while this function is being executed.
+ void (^handler)(GRPCReachabilityFlags *) =
+ (__bridge void (^)(GRPCReachabilityFlags *))info;
handler([[GRPCReachabilityFlags alloc] initWithFlags:flags]);
}
@implementation GRPCConnectivityMonitor {
SCNetworkReachabilityRef _reachabilityRef;
+ GRPCReachabilityFlags *_previousReachabilityFlags;
}
-- (nullable instancetype)initWithReachability:(nullable SCNetworkReachabilityRef)reachability {
+- (nullable instancetype)initWithReachability:
+ (nullable SCNetworkReachabilityRef)reachability {
if (!reachability) {
return nil;
}
if ((self = [super init])) {
_reachabilityRef = CFRetain(reachability);
_queue = dispatch_get_main_queue();
+ _previousReachabilityFlags = nil;
}
return self;
}
@@ -142,33 +149,46 @@ static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target,
SCNetworkReachabilityRef reachability =
SCNetworkReachabilityCreateWithName(NULL, hostName);
- GRPCConnectivityMonitor *returnValue = [[self alloc] initWithReachability:reachability];
+ GRPCConnectivityMonitor *returnValue =
+ [[self alloc] initWithReachability:reachability];
if (reachability) {
CFRelease(reachability);
}
return returnValue;
}
-- (void)handleLossWithHandler:(void (^)())handler {
+- (void)handleLossWithHandler:(void (^)())handler
+ wifiStatusChangeHandler:(nonnull void (^)())wifiStatusChangeHandler {
+ __weak typeof(self) weakSelf = self;
[self startListeningWithHandler:^(GRPCReachabilityFlags *flags) {
- if (!flags.isHostReachable) {
- handler();
+ typeof(self) strongSelf = weakSelf;
+ if (strongSelf) {
+ if (!flags.reachable) {
+ handler();
+ } else if (strongSelf->_previousReachabilityFlags &&
+ (flags.isWWAN ^
+ strongSelf->_previousReachabilityFlags.isWWAN)) {
+ wifiStatusChangeHandler();
+ }
+ strongSelf->_previousReachabilityFlags = flags;
}
}];
}
- (void)startListeningWithHandler:(void (^)(GRPCReachabilityFlags *))handler {
- // Copy to ensure the handler block is in the heap (and so can't be deallocated when this method
- // returns).
+ // Copy to ensure the handler block is in the heap (and so can't be
+ // deallocated when this method returns).
void (^copiedHandler)(GRPCReachabilityFlags *) = [handler copy];
SCNetworkReachabilityContext context = {
- .version = 0,
- .info = (__bridge void *)copiedHandler,
- .retain = CFRetain,
- .release = CFRelease,
+ .version = 0,
+ .info = (__bridge void *)copiedHandler,
+ .retain = CFRetain,
+ .release = CFRelease,
};
- // The following will retain context.info, and release it when the callback is set to NULL.
- SCNetworkReachabilitySetCallback(_reachabilityRef, PassFlagsToContextInfoBlock, &context);
+ // The following will retain context.info, and release it when the callback is
+ // set to NULL.
+ SCNetworkReachabilitySetCallback(_reachabilityRef,
+ PassFlagsToContextInfoBlock, &context);
SCNetworkReachabilitySetDispatchQueue(_reachabilityRef, _queue);
}
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m
index f8634b448e..0524472f53 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.m
+++ b/src/objective-c/GRPCClient/private/GRPCHost.m
@@ -33,9 +33,9 @@
#import "GRPCHost.h"
+#import <GRPCClient/GRPCCall.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
-#import <GRPCClient/GRPCCall.h>
#ifdef GRPC_COMPILE_WITH_CRONET
#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+Cronet.h>
@@ -43,18 +43,27 @@
#import "GRPCChannel.h"
#import "GRPCCompletionQueue.h"
+#import "GRPCConnectivityMonitor.h"
#import "NSDictionary+GRPC.h"
NS_ASSUME_NONNULL_BEGIN
-// TODO(jcanizales): Generate the version in a standalone header, from templates. Like
+// TODO(jcanizales): Generate the version in a standalone header, from
+// templates. Like
// templates/src/core/surface/version.c.template .
#define GRPC_OBJC_VERSION_STRING @"1.0.0"
static NSMutableDictionary *kHostCache;
+// This connectivity monitor flushes the host cache when connectivity status
+// changes or when connection switch between Wifi and Cellular data, so that a
+// new call will use a new channel. Otherwise, a new call will still use the
+// cached channel which is no longer available and will cause gRPC to hang.
+static GRPCConnectivityMonitor *connectivityMonitor = nil;
+
@implementation GRPCHost {
- // TODO(mlumish): Investigate whether caching channels with strong links is a good idea.
+ // TODO(mlumish): Investigate whether caching channels with strong links is a
+ // good idea.
GRPCChannel *_channel;
}
@@ -74,11 +83,13 @@ static NSMutableDictionary *kHostCache;
return nil;
}
- // To provide a default port, we try to interpret the address. If it's just a host name without
- // scheme and without port, we'll use port 443. If it has a scheme, we pass it untouched to the C
- // gRPC library.
- // TODO(jcanizales): Add unit tests for the types of addresses we want to let pass untouched.
- NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:address]];
+ // To provide a default port, we try to interpret the address. If it's just a
+ // host name without scheme and without port, we'll use port 443. If it has a
+ // scheme, we pass it untouched to the C gRPC library.
+ // TODO(jcanizales): Add unit tests for the types of addresses we want to let
+ // pass untouched.
+ NSURL *hostURL =
+ [NSURL URLWithString:[@"https://" stringByAppendingString:address]];
if (hostURL.host && !hostURL.port) {
address = [hostURL.host stringByAppendingString:@":443"];
}
@@ -88,6 +99,7 @@ static NSMutableDictionary *kHostCache;
dispatch_once(&cacheInitialization, ^{
kHostCache = [NSMutableDictionary dictionary];
});
+
@synchronized(kHostCache) {
GRPCHost *cachedHost = kHostCache[address];
if (cachedHost) {
@@ -99,6 +111,17 @@ static NSMutableDictionary *kHostCache;
_secure = YES;
kHostCache[address] = self;
}
+ // Keep a single monitor to flush the cache if the connectivity status changes
+ // Thread safety guarded by @synchronized(kHostCache)
+ if (!connectivityMonitor) {
+ connectivityMonitor =
+ [GRPCConnectivityMonitor monitorWithHost:hostURL.host];
+ void (^handler)() = ^{
+ [GRPCHost flushChannelCache];
+ };
+ [connectivityMonitor handleLossWithHandler:handler
+ wifiStatusChangeHandler:handler];
+ }
}
return self;
}
@@ -114,7 +137,7 @@ static NSMutableDictionary *kHostCache;
}
+ (void)resetAllHostSettings {
- @synchronized (kHostCache) {
+ @synchronized(kHostCache) {
kHostCache = [NSMutableDictionary dictionary];
}
}
@@ -140,16 +163,19 @@ static NSMutableDictionary *kHostCache;
static NSError *kDefaultRootsError;
static dispatch_once_t loading;
dispatch_once(&loading, ^{
- NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem
- // Do not use NSBundle.mainBundle, as it's nil for tests of library projects.
+ NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem
+ // Do not use NSBundle.mainBundle, as it's nil for tests of library
+ // projects.
NSBundle *bundle = [NSBundle bundleForClass:self.class];
NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"];
NSError *error;
- // Files in PEM format can have non-ASCII characters in their comments (e.g. for the name of the
- // issuer). Load them as UTF8 and produce an ASCII equivalent.
- NSString *contentInUTF8 = [NSString stringWithContentsOfFile:path
- encoding:NSUTF8StringEncoding
- error:&error];
+ // Files in PEM format can have non-ASCII characters in their comments (e.g.
+ // for the name of the issuer). Load them as UTF8 and produce an ASCII
+ // equivalent.
+ NSString *contentInUTF8 =
+ [NSString stringWithContentsOfFile:path
+ encoding:NSUTF8StringEncoding
+ error:&error];
if (contentInUTF8 == nil) {
kDefaultRootsError = error;
return;
@@ -161,17 +187,21 @@ static NSMutableDictionary *kHostCache;
NSData *rootsASCII;
if (pemRootCerts != nil) {
rootsASCII = [pemRootCerts dataUsingEncoding:NSASCIIStringEncoding
- allowLossyConversion:YES];
+ allowLossyConversion:YES];
} else {
if (kDefaultRootsASCII == nil) {
if (errorPtr) {
*errorPtr = kDefaultRootsError;
}
- NSAssert(kDefaultRootsASCII, @"Could not read gRPCCertificates.bundle/roots.pem. This file, "
- "with the root certificates, is needed to establish secure (TLS) connections. "
- "Because the file is distributed with the gRPC library, this error is usually a sign "
- "that the library wasn't configured correctly for your project. Error: %@",
- kDefaultRootsError);
+ NSAssert(kDefaultRootsASCII,
+ @"Could not read gRPCCertificates.bundle/roots.pem. This file, "
+ "with the root certificates, is needed to establish secure "
+ "(TLS) connections. "
+ "Because the file is distributed with the gRPC library, this "
+ "error is usually a sign "
+ "that the library wasn't configured correctly for your "
+ "project. Error: %@",
+ kDefaultRootsError);
return NO;
}
rootsASCII = kDefaultRootsASCII;
@@ -182,10 +212,12 @@ static NSMutableDictionary *kHostCache;
creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL);
} else {
grpc_ssl_pem_key_cert_pair key_cert_pair;
- NSData *privateKeyASCII = [pemPrivateKey dataUsingEncoding:NSASCIIStringEncoding
- allowLossyConversion:YES];
- NSData *certChainASCII = [pemCertChain dataUsingEncoding:NSASCIIStringEncoding
- allowLossyConversion:YES];
+ NSData *privateKeyASCII =
+ [pemPrivateKey dataUsingEncoding:NSASCIIStringEncoding
+ allowLossyConversion:YES];
+ NSData *certChainASCII =
+ [pemCertChain dataUsingEncoding:NSASCIIStringEncoding
+ allowLossyConversion:YES];
key_cert_pair.private_key = privateKeyASCII.bytes;
key_cert_pair.cert_chain = certChainASCII.bytes;
creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL);
@@ -205,7 +237,8 @@ static NSMutableDictionary *kHostCache;
NSMutableDictionary *args = [NSMutableDictionary dictionary];
// 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;
if (_userAgentPrefix) {
userAgent = [_userAgentPrefix stringByAppendingFormat:@" %@", userAgent];
@@ -219,7 +252,7 @@ static NSMutableDictionary *kHostCache;
if (_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;
return args;
}
@@ -230,31 +263,35 @@ static NSMutableDictionary *kHostCache;
BOOL useCronet = [GRPCCall isUsingCronet];
#endif
if (_secure) {
- GRPCChannel *channel;
- @synchronized(self) {
- if (_channelCreds == nil) {
- [self setTLSPEMRootCerts:nil withPrivateKey:nil withCertChain:nil error:nil];
- }
+ GRPCChannel *channel;
+ @synchronized(self) {
+ if (_channelCreds == nil) {
+ [self setTLSPEMRootCerts:nil
+ withPrivateKey:nil
+ withCertChain:nil
+ error:nil];
+ }
#ifdef GRPC_COMPILE_WITH_CRONET
- if (useCronet) {
- channel = [GRPCChannel secureCronetChannelWithHost:_address
- channelArgs:args];
- } else
+ if (useCronet) {
+ channel =
+ [GRPCChannel secureCronetChannelWithHost:_address channelArgs:args];
+ } else
#endif
- {
- channel = [GRPCChannel secureChannelWithHost:_address
- credentials:_channelCreds
- channelArgs:args];
- }
+ {
+ channel = [GRPCChannel secureChannelWithHost:_address
+ credentials:_channelCreds
+ channelArgs:args];
}
- return channel;
+ }
+ return channel;
} else {
return [GRPCChannel insecureChannelWithHost:_address channelArgs:args];
}
}
- (NSString *)hostName {
- // TODO(jcanizales): Default to nil instead of _address when Issue #2635 is clarified.
+ // TODO(jcanizales): Default to nil instead of _address when Issue #2635 is
+ // clarified.
return _hostNameOverride ?: _address;
}
diff --git a/src/objective-c/GRPCClient/private/GRPCReachabilityFlagNames.xmacro.h b/src/objective-c/GRPCClient/private/GRPCReachabilityFlagNames.xmacro.h
index 4b92504b55..f5b9e7e64c 100644
--- a/src/objective-c/GRPCClient/private/GRPCReachabilityFlagNames.xmacro.h
+++ b/src/objective-c/GRPCClient/private/GRPCReachabilityFlagNames.xmacro.h
@@ -55,7 +55,7 @@
#endif
#if TARGET_OS_IPHONE
-GRPC_XMACRO_ITEM(isCell, IsWWAN)
+GRPC_XMACRO_ITEM(isWWAN, IsWWAN)
#endif
GRPC_XMACRO_ITEM(reachable, Reachable)
GRPC_XMACRO_ITEM(transientConnection, TransientConnection)
diff --git a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
index c6a03c145e..58c6032e80 100644
--- a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
+++ b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
@@ -38,9 +38,10 @@
#import "NSDictionary+GRPC.h"
// Used by the setter.
-static void CheckIsNonNilASCII(NSString *name, NSString* value) {
+static void CheckIsNonNilASCII(NSString *name, NSString *value) {
if (!value) {
- [NSException raise:NSInvalidArgumentException format:@"%@ cannot be nil", name];
+ [NSException raise:NSInvalidArgumentException
+ format:@"%@ cannot be nil", name];
}
if (![value canBeConvertedToEncoding:NSASCIIStringEncoding]) {
[NSException raise:NSInvalidArgumentException
@@ -52,15 +53,20 @@ static void CheckIsNonNilASCII(NSString *name, NSString* value) {
static void CheckKeyValuePairIsValid(NSString *key, id value) {
if ([key hasSuffix:@"-bin"]) {
if (![value isKindOfClass:NSData.class]) {
- [NSException raise:NSInvalidArgumentException
- format:@"Expected NSData value for header %@ ending in \"-bin\", "
- @"instead got %@", key, value];
+ [NSException
+ raise:NSInvalidArgumentException
+ format:@"Expected NSData value for header %@ ending in \"-bin\", "
+ @"instead got %@",
+ key, value];
}
} else {
if (![value isKindOfClass:NSString.class]) {
- [NSException raise:NSInvalidArgumentException
- format:@"Expected NSString value for header %@ not ending in \"-bin\", "
- @"instead got %@", key, value];
+ [NSException
+ raise:NSInvalidArgumentException
+ format:
+ @"Expected NSString value for header %@ not ending in \"-bin\", "
+ @"instead got %@",
+ key, value];
}
CheckIsNonNilASCII(@"Text header value", (NSString *)value);
}
@@ -68,9 +74,10 @@ static void CheckKeyValuePairIsValid(NSString *key, id value) {
@implementation GRPCRequestHeaders {
__weak GRPCCall *_call;
- // The NSMutableDictionary superclass doesn't hold any storage (so that people can implement their
- // own in subclasses). As that's not the reason we're subclassing, we just delegate storage to the
- // default NSMutableDictionary subclass returned by the cluster (e.g. __NSDictionaryM on iOS 9).
+ // The NSMutableDictionary superclass doesn't hold any storage (so that people
+ // can implement their own in subclasses). As that's not the reason we're
+ // subclassing, we just delegate storage to the default NSMutableDictionary
+ // subclass returned by the cluster (e.g. __NSDictionaryM on iOS 9).
NSMutableDictionary *_delegate;
}
@@ -91,7 +98,8 @@ static void CheckKeyValuePairIsValid(NSString *key, id value) {
}
// Designated initializer
-- (instancetype)initWithCall:(GRPCCall *)call storage:(NSMutableDictionary *)storage {
+- (instancetype)initWithCall:(GRPCCall *)call
+ storage:(NSMutableDictionary *)storage {
// TODO(jcanizales): Throw if call or storage are nil.
if ((self = [super init])) {
_call = call;
@@ -100,9 +108,10 @@ static void CheckKeyValuePairIsValid(NSString *key, id value) {
return self;
}
-- (instancetype)initWithObjects:(const id _Nonnull __unsafe_unretained *)objects
- forKeys:(const id<NSCopying> _Nonnull __unsafe_unretained *)keys
- count:(NSUInteger)cnt {
+- (instancetype)
+initWithObjects:(const id _Nonnull __unsafe_unretained *)objects
+ forKeys:(const id<NSCopying> _Nonnull __unsafe_unretained *)keys
+ count:(NSUInteger)cnt {
return [self init];
}
@@ -134,7 +143,7 @@ static void CheckKeyValuePairIsValid(NSString *key, id value) {
return _delegate.count;
}
-- (NSEnumerator * _Nonnull)keyEnumerator {
+- (NSEnumerator *_Nonnull)keyEnumerator {
return [_delegate keyEnumerator];
}
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
index 627b6aa86d..bbda9f2f64 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
@@ -34,27 +34,27 @@
#import "GRPCWrappedCall.h"
#import <Foundation/Foundation.h>
-#include <grpc/grpc.h>
#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#import "GRPCCompletionQueue.h"
#import "GRPCHost.h"
-#import "NSDictionary+GRPC.h"
#import "NSData+GRPC.h"
+#import "NSDictionary+GRPC.h"
#import "NSError+GRPC.h"
@implementation GRPCOperation {
-@protected
- // Most operation subclasses don't set any flags in the grpc_op, and rely on the flag member being
- // initialized to zero.
+ @protected
+ // Most operation subclasses don't set any flags in the grpc_op, and rely on
+ // the flag member being initialized to zero.
grpc_op _op;
- void(^_handler)();
+ void (^_handler)();
}
- (void)finish {
if (_handler) {
- void(^handler)() = _handler;
+ void (^handler)() = _handler;
_handler = nil;
handler();
}
@@ -101,7 +101,8 @@
- (instancetype)initWithMessage:(NSData *)message handler:(void (^)())handler {
if (!message) {
- [NSException raise:NSInvalidArgumentException format:@"message cannot be nil"];
+ [NSException raise:NSInvalidArgumentException
+ format:@"message cannot be nil"];
}
if (self = [super init]) {
_op.op = GRPC_OP_SEND_MESSAGE;
@@ -137,11 +138,11 @@
grpc_metadata_array _headers;
}
-- (instancetype) init {
+- (instancetype)init {
return [self initWithHandler:nil];
}
-- (instancetype) initWithHandler:(void (^)(NSDictionary *))handler {
+- (instancetype)initWithHandler:(void (^)(NSDictionary *))handler {
if (self = [super init]) {
_op.op = GRPC_OP_RECV_INITIAL_METADATA;
grpc_metadata_array_init(&_headers);
@@ -152,7 +153,7 @@
_handler = ^{
__strong typeof(self) strongSelf = weakSelf;
NSDictionary *metadata = [NSDictionary
- grpc_dictionaryFromMetadataArray:strongSelf->_headers];
+ grpc_dictionaryFromMetadataArray:strongSelf->_headers];
handler(metadata);
};
}
@@ -166,7 +167,7 @@
@end
-@implementation GRPCOpRecvMessage{
+@implementation GRPCOpRecvMessage {
grpc_byte_buffer *_receivedMessage;
}
@@ -192,18 +193,18 @@
@end
-@implementation GRPCOpRecvStatus{
+@implementation GRPCOpRecvStatus {
grpc_status_code _statusCode;
char *_details;
size_t _detailsCapacity;
grpc_metadata_array _trailers;
}
-- (instancetype) init {
+- (instancetype)init {
return [self initWithHandler:nil];
}
-- (instancetype) initWithHandler:(void (^)(NSError *, NSDictionary *))handler {
+- (instancetype)initWithHandler:(void (^)(NSError *, NSDictionary *))handler {
if (self = [super init]) {
_op.op = GRPC_OP_RECV_STATUS_ON_CLIENT;
_op.data.recv_status_on_client.status = &_statusCode;
@@ -216,10 +217,11 @@
__weak typeof(self) weakSelf = self;
_handler = ^{
__strong typeof(self) strongSelf = weakSelf;
- NSError *error = [NSError grpc_errorFromStatusCode:strongSelf->_statusCode
- details:strongSelf->_details];
+ NSError *error =
+ [NSError grpc_errorFromStatusCode:strongSelf->_statusCode
+ details:strongSelf->_details];
NSDictionary *trailers = [NSDictionary
- grpc_dictionaryFromMetadataArray:strongSelf->_trailers];
+ grpc_dictionaryFromMetadataArray:strongSelf->_trailers];
handler(error, trailers);
};
}
@@ -245,20 +247,21 @@
return [self initWithHost:nil path:nil];
}
-- (instancetype)initWithHost:(NSString *)host
- path:(NSString *)path {
+- (instancetype)initWithHost:(NSString *)host path:(NSString *)path {
if (!path || !host) {
[NSException raise:NSInvalidArgumentException
format:@"path and host cannot be nil."];
}
if (self = [super init]) {
- // Each completion queue consumes one thread. There's a trade to be made between creating and
- // consuming too many threads and having contention of multiple calls in a single completion
- // queue. Currently we use a singleton queue.
+ // Each completion queue consumes one thread. There's a trade to be made
+ // between creating and consuming too many threads and having contention of
+ // multiple calls in a single completion queue. Currently we use a singleton
+ // queue.
_queue = [GRPCCompletionQueue completionQueue];
- _call = [[GRPCHost hostWithAddress:host] unmanagedCallWithPath:path completionQueue:_queue];
+ _call = [[GRPCHost hostWithAddress:host] unmanagedCallWithPath:path
+ completionQueue:_queue];
if (_call == NULL) {
return nil;
}
@@ -270,32 +273,35 @@
[self startBatchWithOperations:operations errorHandler:nil];
}
-- (void)startBatchWithOperations:(NSArray *)operations errorHandler:(void (^)())errorHandler {
+- (void)startBatchWithOperations:(NSArray *)operations
+ errorHandler:(void (^)())errorHandler {
size_t nops = operations.count;
grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op));
size_t i = 0;
for (GRPCOperation *operation in operations) {
ops_array[i++] = operation.op;
}
- grpc_call_error error = grpc_call_start_batch(_call, ops_array, nops,
- (__bridge_retained void *)(^(bool success){
- if (!success) {
- if (errorHandler) {
- errorHandler();
- } else {
- return;
- }
- }
- for (GRPCOperation *operation in operations) {
- [operation finish];
- }
- }), NULL);
+ grpc_call_error error = grpc_call_start_batch(
+ _call, ops_array, nops, (__bridge_retained void *)(^(bool success) {
+ if (!success) {
+ if (errorHandler) {
+ errorHandler();
+ } else {
+ return;
+ }
+ }
+ for (GRPCOperation *operation in operations) {
+ [operation finish];
+ }
+ }),
+ NULL);
gpr_free(ops_array);
if (error != GRPC_CALL_OK) {
[NSException raise:NSInternalInconsistencyException
- format:@"A precondition for calling grpc_call_start_batch wasn't met. Error %i",
- error];
+ format:@"A precondition for calling grpc_call_start_batch "
+ @"wasn't met. Error %i",
+ error];
}
}
diff --git a/src/objective-c/GRPCClient/private/NSError+GRPC.h b/src/objective-c/GRPCClient/private/NSError+GRPC.h
index e0c1efc1f9..a9a321470c 100644
--- a/src/objective-c/GRPCClient/private/NSError+GRPC.h
+++ b/src/objective-c/GRPCClient/private/NSError+GRPC.h
@@ -36,8 +36,9 @@
@interface NSError (GRPC)
/**
- * Returns nil if the status code is OK. Otherwise, a NSError whose code is one of |GRPCErrorCode|
- * and whose domain is |kGRPCErrorDomain|.
+ * Returns nil if the status code is OK. Otherwise, a NSError whose code is one
+ * of |GRPCErrorCode| and whose domain is |kGRPCErrorDomain|.
*/
-+ (instancetype)grpc_errorFromStatusCode:(grpc_status_code)statusCode details:(char *)details;
++ (instancetype)grpc_errorFromStatusCode:(grpc_status_code)statusCode
+ details:(char *)details;
@end