diff --git a/gRPC.podspec b/gRPC.podspec
index 22ecdcf66f1f01234589c71aa57e57ea44f2e590..4c83ccc7a0fe3dcd26d028d6d36e83e87674a169 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -40,9 +40,12 @@ Pod::Spec.new do |s|
   s.header_dir = name
 
   src_dir = 'src/objective-c/GRPCClient'
+  s.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}"
+  s.private_header_files = "#{src_dir}/private/*.h"
+  s.header_mappings_dir = "#{src_dir}"
 
+  s.dependency 'gRPC-Core', version
   s.dependency 'gRPC-RxLibrary', version
-  s.default_subspec = 'Main'
 
   # Certificates, to be able to establish TLS connections:
   s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] }
@@ -51,22 +54,4 @@ Pod::Spec.new do |s|
     # This is needed by all pods that depend on gRPC-RxLibrary:
     'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
   }
-
-  s.subspec 'Main' do |ss|
-    ss.header_mappings_dir = "#{src_dir}"
-
-    ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}"
-    ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}"
-    ss.private_header_files = "#{src_dir}/private/*.h"
-
-    ss.dependency 'gRPC-Core', version
-  end
-
-  s.subspec 'GID' do |ss|
-    ss.header_mappings_dir = "#{src_dir}"
-
-    ss.source_files = "#{src_dir}/GRPCCall+GID.{h,m}"
-
-    ss.dependency 'Google/SignIn'
-  end
 end
diff --git a/src/objective-c/GRPCClient/GRPCCall+GID.h b/src/objective-c/GRPCClient/GRPCCall+GID.h
deleted file mode 100644
index 3ee732e79ea3e3a62e63caa07d925ec4c8458674..0000000000000000000000000000000000000000
--- a/src/objective-c/GRPCClient/GRPCCall+GID.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#import "GRPCCall.h"
-#import "GRPCCall+OAuth2.h"
-
-#import <Google/SignIn.h>
-
-/**
- * Extend GIDSignIn class to comply GRPCAuthorizationProtocol
- */
-@interface GIDSignIn (GRPC) <GRPCAuthorizationProtocol>
-- (void)getTokenWithHandler:(void (^)(NSString *token))hander;
-@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+GID.m b/src/objective-c/GRPCClient/GRPCCall+GID.m
deleted file mode 100644
index 030737147b58255109950d07d9634b11c45fa076..0000000000000000000000000000000000000000
--- a/src/objective-c/GRPCClient/GRPCCall+GID.m
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#import "GRPCCall+GID.h"
-
-@implementation GIDSignIn (GRPC)
-
-- (void)getTokenWithHandler:(void (^)(NSString *token))handler {
-  NSString *token = self.currentUser.authentication.accessToken;
-  handler(token);
-}
-
-@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h
index adb1042aa0ebbbce8a48c729819c973e8e0c587d..65465e9523621ed03f50b2cf44451b159469b000 100644
--- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h
+++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h
@@ -18,13 +18,6 @@
 
 #import "GRPCCall.h"
 
-/**
- * The protocol of an OAuth2 token object from which GRPCCall can acquire a token.
- */
-@protocol GRPCAuthorizationProtocol
-- (void)getTokenWithHandler:(void (^)(NSString *token))hander;
-@end
-
 /** Helpers for setting and reading headers compatible with OAuth2. */
 @interface GRPCCall (OAuth2)
 
@@ -40,12 +33,4 @@
 /** Returns the value (if any) of the "www-authenticate" response header (the challenge header). */
 @property(atomic, readonly) NSString *oauth2ChallengeHeader;
 
-/**
- * The authorization token object to be used when starting the call. If the value is set to nil, no
- * oauth authentication will be used.
- *
- * If tokenProvider exists, it takes precedence over the token set by oauth2AccessToken.
- */
-@property(atomic, strong) id<GRPCAuthorizationProtocol> tokenProvider;
-
 @end
diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.m b/src/objective-c/GRPCClient/GRPCCall+OAuth2.m
index 8451ebe870e34c1d8d2a0704c7d091e7cb86d4d4..eaa7465087019c6f1f2cd2d6ff59524a250dd120 100644
--- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.m
+++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.m
@@ -16,8 +16,6 @@
  *
  */
 
-#import <objc/runtime.h>
-
 #import "GRPCCall+OAuth2.h"
 
 static NSString * const kAuthorizationHeader = @"authorization";
@@ -25,7 +23,6 @@ static NSString * const kBearerPrefix = @"Bearer ";
 static NSString * const kChallengeHeader = @"www-authenticate";
 
 @implementation GRPCCall (OAuth2)
-@dynamic tokenProvider;
 
 - (NSString *)oauth2AccessToken {
   NSString *headerValue = self.requestHeaders[kAuthorizationHeader];
@@ -48,12 +45,4 @@ static NSString * const kChallengeHeader = @"www-authenticate";
   return self.responseHeaders[kChallengeHeader];
 }
 
-- (void)setTokenProvider:(id<GRPCAuthorizationProtocol>)tokenProvider {
-  objc_setAssociatedObject(self, @selector(tokenProvider), tokenProvider, OBJC_ASSOCIATION_RETAIN);
-}
-
-- (id<GRPCAuthorizationProtocol>)tokenProvider {
-  return objc_getAssociatedObject(self, @selector(tokenProvider));
-}
-
 @end
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index 436c19e354a609e183d71222a659da87e93b04d1..872362419eb3a450ad8a3a45557dd5a8aeee75a2 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -18,8 +18,6 @@
 
 #import "GRPCCall.h"
 
-#import "GRPCCall+OAuth2.h"
-
 #include <grpc/grpc.h>
 #include <grpc/support/time.h>
 #import <RxLibrary/GRXConcurrentWriteable.h>
@@ -42,14 +40,10 @@ NSString * const kGRPCHeadersKey = @"io.grpc.HeadersKey";
 NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
 static NSMutableDictionary *callFlags;
 
-static NSString * const kAuthorizationHeader = @"authorization";
-static NSString * const kBearerPrefix = @"Bearer ";
-
 @interface GRPCCall () <GRXWriteable>
 // Make them read-write.
 @property(atomic, strong) NSDictionary *responseHeaders;
 @property(atomic, strong) NSDictionary *responseTrailers;
-@property(atomic) BOOL isWaitingForToken;
 @end
 
 // The following methods of a C gRPC call object aren't reentrant, and thus
@@ -187,6 +181,9 @@ static NSString * const kBearerPrefix = @"Bearer ";
 
 - (void)finishWithError:(NSError *)errorOrNil {
   @synchronized(self) {
+    if (_state == GRXWriterStateFinished) {
+      return;
+    }
     _state = GRXWriterStateFinished;
   }
 
@@ -214,11 +211,7 @@ static NSString * const kBearerPrefix = @"Bearer ";
   [self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
                                             code:GRPCErrorCodeCancelled
                                         userInfo:@{NSLocalizedDescriptionKey: @"Canceled by app"}]];
-  if (!self.isWaitingForToken) {
-    [self cancelCall];
-  } else {
-    self.isWaitingForToken = NO;
-  }
+  [self cancelCall];
 }
 
 - (void)dealloc {
@@ -417,13 +410,22 @@ static NSString * const kBearerPrefix = @"Bearer ";
 
 #pragma mark GRXWriter implementation
 
-- (void)startCallWithWriteable:(id<GRXWriteable>)writeable {
+- (void)startWithWriteable:(id<GRXWriteable>)writeable {
+  @synchronized(self) {
+    _state = GRXWriterStateStarted;
+  }
+
+  // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled).
+  // This makes RPCs in which the call isn't externally retained possible (as long as it is started
+  // before being autoreleased).
+  // Care is taken not to retain self strongly in any of the blocks used in this implementation, so
+  // that the life of the instance is determined by this retain cycle.
+  _retainSelf = self;
+
   _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable
                                                            dispatchQueue:_responseQueue];
 
-  _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host
-                                            serverName:_serverName
-                                                  path:_path];
+  _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host serverName:_serverName path:_path];
   NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?");
 
   [self sendHeaders:_requestHeaders];
@@ -435,49 +437,20 @@ static NSString * const kBearerPrefix = @"Bearer ";
     // TODO(jcanizales): Check this on init.
     [NSException raise:NSInvalidArgumentException format:@"host of %@ is nil", _host];
   }
-  _connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:host];
   __weak typeof(self) weakSelf = self;
+  _connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:host];
   void (^handler)() = ^{
     typeof(self) strongSelf = weakSelf;
-    [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
-                                                    code:GRPCErrorCodeUnavailable
-                                                userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]];
+    if (strongSelf) {
+      [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+                                                      code:GRPCErrorCodeUnavailable
+                                                  userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]];
+    }
   };
   [_connectivityMonitor handleLossWithHandler:handler
                       wifiStatusChangeHandler:nil];
 }
 
-- (void)startWithWriteable:(id<GRXWriteable>)writeable {
-  @synchronized(self) {
-    _state = GRXWriterStateStarted;
-  }
-
-  // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled).
-  // This makes RPCs in which the call isn't externally retained possible (as long as it is started
-  // before being autoreleased).
-  // Care is taken not to retain self strongly in any of the blocks used in this implementation, so
-  // that the life of the instance is determined by this retain cycle.
-  _retainSelf = self;
-
-  if (self.tokenProvider != nil) {
-    self.isWaitingForToken = YES;
-    __weak typeof(self) weakSelf = self;
-    [self.tokenProvider getTokenWithHandler:^(NSString *token){
-      typeof(self) strongSelf = weakSelf;
-      if (strongSelf && strongSelf.isWaitingForToken) {
-        if (token) {
-          NSString *t = [kBearerPrefix stringByAppendingString:token];
-          strongSelf.requestHeaders[kAuthorizationHeader] = t;
-        }
-        [strongSelf startCallWithWriteable:writeable];
-        strongSelf.isWaitingForToken = NO;
-      }
-    }];
-  } else {
-    [self startCallWithWriteable:writeable];
-  }
-}
-
 - (void)setState:(GRXWriterState)newState {
   @synchronized(self) {
     // Manual transitions are only allowed from the started or paused states.
diff --git a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
index 5de1d8fff5f51dea9e9ef8458e890746a07e33ff..7640a64d6db08d3f2a2f336a2565abf0f7b25c3d 100644
--- a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
+++ b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
@@ -103,6 +103,7 @@ static void CheckKeyValuePairIsValid(NSString *key, id value) {
 }
 
 - (void)setObject:(id)obj forKey:(NSString *)key {
+  [self checkCallIsNotStarted];
   CheckIsNonNilASCII(@"Header name", key);
   key = key.lowercaseString;
   CheckKeyValuePairIsValid(key, obj);
diff --git a/templates/gRPC.podspec.template b/templates/gRPC.podspec.template
index 5c92f9f9c42b41f57f6e6896d461d9de67176e3c..62a6d37c3c70b2b31f3bebe0f3c2d747212401cd 100644
--- a/templates/gRPC.podspec.template
+++ b/templates/gRPC.podspec.template
@@ -42,9 +42,12 @@
     s.header_dir = name
 
     src_dir = 'src/objective-c/GRPCClient'
+    s.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}"
+    s.private_header_files = "#{src_dir}/private/*.h"
+    s.header_mappings_dir = "#{src_dir}"
 
+    s.dependency 'gRPC-Core', version
     s.dependency 'gRPC-RxLibrary', version
-    s.default_subspec = 'Main'
 
     # Certificates, to be able to establish TLS connections:
     s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] }
@@ -53,22 +56,4 @@
       # This is needed by all pods that depend on gRPC-RxLibrary:
       'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
     }
-
-    s.subspec 'Main' do |ss|
-      ss.header_mappings_dir = "#{src_dir}"
-
-      ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}"
-      ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}"
-      ss.private_header_files = "#{src_dir}/private/*.h"
-
-      ss.dependency 'gRPC-Core', version
-    end
-
-    s.subspec 'GID' do |ss|
-      ss.header_mappings_dir = "#{src_dir}"
-
-      ss.source_files = "#{src_dir}/GRPCCall+GID.{h,m}"
-
-      ss.dependency 'Google/SignIn'
-    end
   end