8

I am trying to convert my coredata to json, I have been struggling to get this to work but have found a way that is almost working.

my code:

NSArray *keys = [[[self.form entity] attributesByName] allKeys];
        NSDictionary *dict = [self.form dictionaryWithValuesForKeys:keys];
        NSLog(@"dict::%@",dict);

        NSError *error;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict
                                                           options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
                                                             error:&error];

        if (! jsonData) {
            NSLog(@"Got an error: %@", error);
        } else {
            NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
            NSLog(@"json::%@",jsonString);
        }

also "form" is:

 @property (strong, retain) NSManagedObject *form;

This works fine except I have NSIndexSet saved in some of the coredata attributes. This poses a problem with the JSON write. Now, my indexsets do not need to be converted to json so I was wondering if there was a way to delete all indexes from the dict? or maybe there is a better way to do this I am unaware of.

here is part of the nslog of dict:

...
    whereExtent = "";
    wiring =     (
    );
    wiring1 = "<NSIndexSet: 0x82b0600>(no indexes)";
    wiringUpdated = "<null>";
    yardFenceTrees = "<null>";
}

so in this case I want to remove "wiring1" from dict but need to be able to do it in a "dynamic" way (not using the name "wiring1" to remove it)

BluGeni
  • 3,378
  • 8
  • 36
  • 64
  • possible duplicate of [Obj-C easy method to convert from NSObject with properties to NSDictionary?](http://stackoverflow.com/questions/10318366/obj-c-easy-method-to-convert-from-nsobject-with-properties-to-nsdictionary) – Abizern Nov 05 '13 at 15:05
  • @Abizern All I want to do is remove nsindexset (key and value) from my dict, How is this a duplicate of that question? – BluGeni Nov 05 '13 at 15:32
  • Do you have array, set or dictionary properties as part of this object, or is it just a straight list of properties? – jrturton Nov 05 '13 at 16:13

3 Answers3

21

To be able to delete values, your dictionary must be an instance of NSMutableDictionary class.

For dynamically removing values, get all keys from dict, test the object of each key and remove unnecessary objects:

NSArray *keys = [dict allKeys];
for (int i = 0 ; i < [keys count]; i++)
 {
   if ([dict[keys[i]] isKindOfClass:[NSIndexSet class]])
   {
     [dict removeObjectForKey:keys[i]];
   }
}

Note: Removing values does not work with fast enumeration. As an alternative fast hack, you may create a new dictionary without unnecessary objects.

kk1
  • 53
  • 4
Ruslan Soldatenko
  • 1,718
  • 17
  • 25
  • This is almost perfect but I think I need to be checking the value of the key for each key because when I check the key its just (class) _PFEncodeString – BluGeni Nov 05 '13 at 16:31
8

Use NSMutableDictionary instead NSDictionary.Your code will looks like:

NSMutableDictionary *dict = [[self.form dictionaryWithValuesForKeys:keys] mutableCopy]; //create dict
[dict removeObjectForKey:@"wiring1"]; //remove object

Don't forget use mutableCopy.

Kisel Alexander
  • 750
  • 2
  • 8
  • 25
1

This sample code will pass through an NSDictionary and build a new NSMutableDictionary containing only JSON-safe properties.

At the moment it does not work recursively, e.g. if your dictionary contains a dictionary or array, it will drop it rather than pass through the dictionary itself and fix that, but that is simple enough to add.

// Note: does not work recursively, e.g. if the dictionary contains an array or dictionary it will be dropped.
NSArray *allowableClasses = @[[NSString class], [NSNumber class], [NSDate class], [NSNull class]];
NSDictionary *properties = @{@"a":@"hello",@"B":[[NSIndexSet alloc] init]};
NSMutableDictionary *safeProperties = [[NSMutableDictionary alloc] init];

[properties enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){
    BOOL allowable = NO;
    for (Class allowableClass in allowableClasses)          {
        if ([obj isKindOfClass:allowableClass])
        {
            allowable = YES;
            break;
        }
    }       
    if (allowable)
    {
        safeProperties[key] = obj;
    }
}];
NSLog(@"unsafe: %@, safe: %@",properties,safeProperties);
jrturton
  • 118,105
  • 32
  • 252
  • 268