I'm using NSJSONSerialization
to grab some JSON and parse it into a custom NSObject
subclass. That works just fine, and I can retrieve values out of it using:
CustomProperties* properties = [[CustomProperties alloc] init];
[properties objectForKey:@"nameOfKey"]
Simple implementation for my subclass:
CustomProperties.h
#import <Foundation/Foundation.h>
@interface CustomProperties : NSObject
- (id)objectForKey:(NSString *)key;
@end
CustomProperties.m
@implementation CustomProperties
-(id) init {
if (self = [super init]) {
/* do most of initialization */
}
return(self);
}
- (id)objectForKey:(NSString *)key
{
return nil;
}
@end
The problem
I'm trying to add a custom instance method that can process the retrieved value into a float using a default value if the retrieved JSON value is nil.
My thought was something simple like:
CustomProperties.h
@interface CustomProperties : NSObject
// ...existing id interface here
- (CGFloat)getFloatValueForKey:(NSString*)key defaultValue:(CGFloat)defaultValue;
@end
CustomProperties.m
@implementation CustomProperties
// ...existing id method here
- (CGFloat)getFloatValueForKey:(NSString*)key defaultValue:(CGFloat)defaultValue
{
if (key == nil)
return 0;
if ([self objectForKey:key] == nil)
return defaultValue;
else
return [[self objectForKey:key] floatValue];
}
@end
So that I can then call it like:
CustomProperties* properties = [[CustomProperties alloc] init];
[properties getFloatValueForKey:@"nameOfKey" defaultValue:0.2];
This of course causes a whopping:
-[__NSCFDictionary getFloatValueForKey:defaultValue:]:
unrecognized selector sent to instance
'NSInvalidArgumentException', reason: '-[__NSCFDictionary getFloatValueForKey:defaultValue:]:
unrecognized selector sent to instance
I truly understand that it's not implemented properly and that I'm missing something! Just don't know what.
Edit
Digging deeper, it appears that when it's first being initialized (when I'm parsing the JSON) it's setting it to type __NSCFDictionary
:
CustomProperties* properties = [[CustomProperties alloc] init];
properties = [jsonNSDictionaryObjectInstance objectForKey:@"properties"];
customDetailsInstance.properties = properties;
I had to create a custom initWithProperties
method that captured the incoming NSCFDictionary and parse the properties using objectForKey
.
When parsing the JSON:
// jsonNSDictionaryObjectInstance is actually an __NSCFDictionary
CustomProperties* properties = [[CustomProperties alloc] initinitWithProperties[initWithProperties objectForKey@"theJSONKeyYouAreParsing"]];
customDetailsInstance.properties = properties;
And then for the CustomProperties class:
.h
- (id)initWithProperties:(NSDictionary*)properties;
@property (nonatomic) CGFloat aCustomProperty;
@property (nonatomic) CGFloat anotherCustomProperty;
.m
-(id) initWithProperties:(NSDictionary*)properties
{
if (self = [super init]) {
/* do most of initialization */
self.aCustomProperty = [[properties objectForKey:@"jsonSubKey"] floatValue];
self.anotherCustomProperty = [[properties objectForKey:@"anotherJsonSubkey"] floatValue];
}
return(self);
}