Error with NSJSONSerialization - Invalid type in JSON write (Menu)

后端 未结 4 1176
南方客
南方客 2020-12-03 00:22

I have an App using core data with 3 entities with very similar attributes. The relationship is such as:

Branch ->> Menu ->> Category ->> FoodItem

Each ent

相关标签:
4条回答
  • 2020-12-03 00:58

    There is a class method isValidJSONObject on NSJSONSerialization that tells you if a object can be serialised. As Julien pointed out you probably have to convert your object to a NSDictionary. NSManagedModel provides some handy methods to get all your attributes for your entity. So you could create a category for NSManagedObject that has a method to convert it over to a NSDictionary. This way you don't have to write a toDictionary method for each entity you want to convert to a dictionary.

    @implementation NSManagedObject (JSON)
    
    - (NSDictionary *)toDictionary
    {
        NSArray *attributes = [[self.entity attributesByName] allKeys];
        NSDictionary *dict = [self dictionaryWithValuesForKeys:attributes];
        return dict;
    }
    
    0 讨论(0)
  • 2020-12-03 01:01

    That's because your "Menu" class is not serializable in JSON. Bascially the language doesn't know how your object should be represented in JSON (which fields to include, how to represent references to other objects...)

    From the NSJSONSerialization Class Reference

    An object that may be converted to JSON must have the following properties:

    • The top level object is an NSArray or NSDictionary.
    • All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
    • All dictionary keys are instances of NSString.
    • Numbers are not NaN or infinity.

    This means that the language knows how to serialize dictionaries. So a simple way to get a JSON representation from your menu is to provide a Dictionary representation of your Menu instances, which you will then serialize into JSON:

    - (NSDictionary *)dictionaryFromMenu:(Menu)menu {
        [NSDictionary dictionaryWithObjectsAndKeys:[menu.dateUpdated description],@"dateUpdated",
        menu.categoryId, @"categoryId",
        //... add all the Menu properties you want to include here
        nil];
    }
    

    And you could will use it like this :

    NSDictionary *menuDictionary = [self dictionaryFromMenu:[[DataStore singleton] getHomeMenu]]; 
    
    NSError *err;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:menuDictionary options:NSJSONWritingPrettyPrinted error:&err];
    
    NSLog(@"JSON = %@", [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);
    
    0 讨论(0)
  • 2020-12-03 01:01

    You can use + isValidJSONObject: method of NSJSONSerialization class. If it is not valid, you can use - initWithData:encoding: method of NSString.

    - (NSString *)prettyPrintedJson:(id)jsonObject
    {
        NSData *jsonData;
    
        if ([NSJSONSerialization isValidJSONObject:jsonObject]) {
            NSError *error;
            jsonData = [NSJSONSerialization dataWithJSONObject:jsonObject
                                                               options:NSJSONWritingPrettyPrinted
                                                                 error:&error];
    
            if (error) {
                return nil;
            }
        } else {
            jsonData = jsonObject;
        }
    
        return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    
    0 讨论(0)
  • 2020-12-03 01:22

    I had the key switched with the value : @{value :@"key"} It should be @{@"key":value}

    0 讨论(0)
提交回复
热议问题