diff --git a/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
index 99c890e4ee790b7ed8ae696c80bbfbba34903a98..a7f6d34ed58a3561e2dfdaef2f9ae764ea951032 100644
--- a/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
+++ b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
@@ -40,8 +40,8 @@
 @interface NSData (GRPCMetadata)
 + (instancetype)grpc_dataFromMetadataValue:(grpc_metadata *)metadata;
 
-// Fill a metadata object with the binary value in this NSData and the given key.
-- (void)grpc_initMetadata:(grpc_metadata *)metadata withKey:(NSString *)key;
+// Fill a metadata object with the binary value in this NSData.
+- (void)grpc_initMetadata:(grpc_metadata *)metadata;
 @end
 
 @implementation NSData (GRPCMetadata)
@@ -50,9 +50,7 @@
   return [self dataWithBytes:metadata->value length:metadata->value_length];
 }
 
-- (void)grpc_initMetadata:(grpc_metadata *)metadata withKey:(NSString *)key {
-  // TODO(jcanizales): Encode Unicode chars as ASCII.
-  metadata->key = [key stringByAppendingString:@"-bin"].UTF8String;
+- (void)grpc_initMetadata:(grpc_metadata *)metadata {
   metadata->value = self.bytes;
   metadata->value_length = self.length;
 }
@@ -63,8 +61,8 @@
 @interface NSString (GRPCMetadata)
 + (instancetype)grpc_stringFromMetadataValue:(grpc_metadata *)metadata;
 
-// Fill a metadata object with the textual value in this NSString and the given key.
-- (void)grpc_initMetadata:(grpc_metadata *)metadata withKey:(NSString *)key;
+// Fill a metadata object with the textual value in this NSString.
+- (void)grpc_initMetadata:(grpc_metadata *)metadata;
 @end
 
 @implementation NSString (GRPCMetadata)
@@ -74,22 +72,8 @@
                             encoding:NSASCIIStringEncoding];
 }
 
-- (void)grpc_initMetadata:(grpc_metadata *)metadata withKey:(NSString *)key {
-  if ([key hasSuffix:@"-bin"]) {
-    // Disallow this, as at best it will confuse the server. If the app really needs to send a
-    // textual header with a name ending in "-bin", it can be done by removing the suffix and
-    // encoding the NSString as a NSData object.
-    //
-    // Why raise an exception: In the most common case, the developer knows this won't happen in
-    // their code, so the exception isn't triggered. In the rare cases when the developer can't
-    // tell, it's easy enough to add a sanitizing filter before the header is set. There, the
-    // developer can choose whether to drop such a header, or trim its name. Doing either ourselves,
-    // silently, would be very unintuitive for the user.
-    [NSException raise:NSInvalidArgumentException
-                format:@"Metadata keys ending in '-bin' are reserved for NSData values."];
-  }
-  // TODO(jcanizales): Encode Unicode chars as ASCII.
-  metadata->key = key.UTF8String;
+// Precondition: This object contains only ASCII characters.
+- (void)grpc_initMetadata:(grpc_metadata *)metadata {
   metadata->value = self.UTF8String;
   metadata->value_length = self.length;
 }
@@ -124,19 +108,21 @@
   return metadata;
 }
 
+// Preconditions: All keys are ASCII strings. Keys ending in -bin have NSData values; the others
+// have NSString values.
 - (grpc_metadata *)grpc_metadataArray {
   grpc_metadata *metadata = gpr_malloc([self count] * sizeof(grpc_metadata));
-  int i = 0;
-  for (id key in self) {
+  grpc_metadata *current = metadata;
+  for (NSString* key in self) {
     id value = self[key];
-    grpc_metadata *current = &metadata[i];
-    if ([value respondsToSelector:@selector(grpc_initMetadata:withKey:)]) {
-      [value grpc_initMetadata:current withKey:key];
+    current->key = key.UTF8String;
+    if ([value respondsToSelector:@selector(grpc_initMetadata:)]) {
+      [value grpc_initMetadata:current];
     } else {
       [NSException raise:NSInvalidArgumentException
                   format:@"Metadata values must be NSString or NSData."];
     }
-    i += 1;
+    ++current;
   }
   return metadata;
 }