NSHTTPURLResponse allHeaderFields case sensitivity
key-value-observing, nsdictionary, objective-c
Solution
They aren't both NSCFDictionary
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response
{
NSDictionary *dictionary1 = [(NSHTTPURLResponse*)response allHeaderFields];
NSDictionary *dictionary2 = [NSDictionary dictionaryWithObjects:[dictionary1 allValues] forKeys:[dictionary1 allKeys]];
}
in lldb:
(lldb) po [dictionary2 class]
__NSDictionaryI
(lldb) po [dictionary1 class]
__NSCFDictionary
and seems __NSCFDictionary keys are actually case-insensitive 0_0. Class inheritance looks so for __NSCFDictionary: __NSCFDictinary <-- NSMutableDictionary <-- NSDictionary. For __NSDictionaryI: __NSDictionaryI <-- NSDictionary Check debug output:
(lldb) po [dictionary1 superclass]
NSMutableDictionary
(lldb) po [[dictionary1 superclass] superclass]
NSDictionary
(lldb) po [dictionary2 superclass]
NSDictionary
I also created
NSMutableDictionary *dictionary3 = [dictionary2 mutableCopy];
and tried
(lldb) po [dictionary3 class]
__NSDictionaryM
(lldb) po [[dictionary3 class] superclass]
NSMutableDictionary
(lldb) po [[[dictionary3 class] superclass] superclass]
NSDictionary
(lldb) po dictionary3[@"date"]
nil
(lldb) po dictionary3[@"Date"]
Sun, 01 Dec 2013 13:35:22 GMT
So it seems like only __NSCFDictionary subclass of NSMutableDictionary has case-insensitive keys. And.. i think it's made through `-objectForKey:` `-setObject:forKey:` implementation. Not through custom NSString's. Moreover, this `__NSCFDictionary` is immutable subclass of NSMutableDictionary.. it overrides `setObject:forKey:` to throw exception. So the short answer is: It's done by Apple through some private Foundation dictionary class.
Problem
How come that `-[[NSHTTPURLResponse allHeaderFields] valueForKey:]` is case insensitive, while `valueForKey:` for manually created `NSDictionary` is not? Both seems to be instances of `NSCFDictionary`; Poking the first one with variation of, let's say, `Content-Type`, `content-type`, `ConTEnt-TYPe` returns the same value Manually created `NSDictionary *a = @{ @"content-type" : @"pillows" }` returns `nil` for any spelling other then lowercase "content-type" Edit Turns out this behavior can be easily achieved when dropping down to core foundation level: https://gist.github.com/steipete/7739473