KVC: how to check an existing key

I need a little help with KVC.

A few words about the working context:

1) iPhone connects (client) to the web service to get the object,

2) I am using JSON to transfer data,

3) If the client has exactly the same object mapping, I can iterate over the NSDictionary from the JSON to store the data in persistent storage (coreData). For this I use this piece of code (assume all data is NSString):

NSDictionary *dict = ... dictionary from JSON

NSArray *keyArray = [dict allKeys]; //gets all the properties keys form server

for (NSString *s in keyArray){

[myCoreDataObject setValue:[dict objectForKey:s] forKey:s];  //store the property in the coreData object 

}

      

Now my problem is ....

4) What happens if a server implementing a new version of an object with 1 new property If I pass data to the client and the client is not at the persistence version level (this means the mapping of "old" objects is still in use), I try to assign a value to not existing key ... and I will have a message:

the object "myOldObject" is not a key to encode the key for the key "myNewKey"

Could you please suggest me how to check for the existence of a key in an object, so if the key exists, I can proceed to update the value, avoiding the error message?

Sorry if I am a little confused in explaining my context.

thank

Dario

+2


source to share


1 answer


While I can't think of a way to find out what keys an object will support, you could take advantage of the fact that when you set a value to a non-existent key, your object's default behavior is to throw an exception . You can wrap the method call setValue:forKey:

in a @try

/ block @catch

to handle these errors.

Consider the following code for an object:

@interface KVCClass : NSObject {
    NSString *stuff;
}

@property (nonatomic, retain) NSString *stuff;

@end

@implementation KVCClass

@synthesize stuff;

- (void) dealloc
{
    [stuff release], stuff = nil;

    [super dealloc];
}

@end

      

It should be KVC compliant for the key stuff

, but nothing else.

If you access this class from the following program:



int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    KVCClass *testClass = [[KVCClass alloc] init];

    [testClass setValue:@"this is the value" forKey:@"stuff"];

    NSLog(@"%@", testClass.stuff);

    // Error handled nicely
    @try {
        [testClass setValue:@"this should fail but we will catch the exception" forKey:@"nonexistentKey"];
    }
    @catch (NSException * e) {
        NSLog(@"handle error here");
    }

    // This will throw an exception
    [testClass setValue:@"this will fail" forKey:@"nonexistentKey"];

    [testClass release];
    [pool drain];
    return 0;
}

      

You will get console output similar to the following:

2010-01-08 18:06:57.981 KVCTest[42960:903] this is the value
2010-01-08 18:06:57.984 KVCTest[42960:903] handle error here
2010-01-08 18:06:57.984 KVCTest[42960:903] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<KVCClass 0x10010c680> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key nonexistentKey.'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00007fff851dc444 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff866fa0f3 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff85233a19 -[NSException raise] + 9
    3   Foundation                          0x00007fff85659429 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 434
    4   KVCTest                             0x0000000100001b78 main + 328
    5   KVCTest                             0x0000000100001a28 start + 52
    6   ???                                 0x0000000000000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
Abort trap

      

This shows that the first attempt to access the key nonexistentKey

was well caught by the program, the second threw an exception like yours.

+3


source







All Articles