aryaxt / OCMapper

Objective-C library to easily map NSDictionary to model objects, works perfectly with Alamofire. ObjectMapper works similar to GSON
MIT License
347 stars 45 forks source link

How to specify which property to extract when using dictionaryFromObject() method? #18

Closed hopiaw closed 9 years ago

hopiaw commented 9 years ago

Hi,

When using the following method:

(id)dictionaryFromObject:(NSObject *)object;

and object inherit NSManagedObject, the dictionary returned has a lot of NSManagedObject properties that I'd like to remove (like inserted, deleted, hasChanges, faultingState etc). Is there is an easy way to do that?

Thanks

aryaxt commented 9 years ago

Try using this:

[managedObjectInstanceProvider setUniqueKeys:@[@"userId"] forClass:[User class] withUpsertMode:UpsertModePurgeExistingObject];

UniqueKeys ensure that when it finds an NSManagedObject with existing unique identifier it overrides them instead of creating a new instance.

Having upsert policy set to UpsertModePurgeExistingObject deletes the existing (if it finds an existing) one and creates a brand new one, which means it triggers all your cascade delete rules

Let me know if this does what you are looking for

hopiaw commented 9 years ago

Thanks for the quick reply. This is not my issue I think. I'm actually setting a unique key for my class with the mode UpsertModeUpdateExistingObject. It works great.

But when I want to generate a dictionary from my object model, the dictionary returned has all the objects properties plus the ones related to any NSManagedObject class.

For example, for the following class:

class MyClass
{
    var name:String
    var age:Int  
}

I'll get a dictionary with maybe 10 key/value pairs more than the number of the object properties:

"name": .... "age": ... "faultingState": .... "deleted": 0 "existingID":.... etc...

I'd like to obtain a dictionary that contains only the properties of my object. Hope it's more clear.

aryaxt commented 9 years ago

Got it, I used the runtime API for all object to dictionary conversion. Need to change it to use NSPropertyDescription for NSManagedObjects. Will make that change on the next version

hopiaw commented 9 years ago

Cool, thanks a lot!

poetmountain commented 9 years ago

This would be really helpful for regular NSObjects as well; I'm currently running into this issue with my own NSObject models. Also, sometimes I only want to send changed properties to a PATCH request. So perhaps it would be better to be able to submit a whitelist of properties you want published, maybe via a new dictionaryFromObject: withWhiteList: method so that whitelists can be defined as-needed.

aryaxt commented 9 years ago

@hopiaw @poetmountain I'm adding this feature today. Would the following method get the job done for what you guys are trying to achieve? Guessing you could loop through all NSManagedObjects dynamically and call exclude on all, or maybe you could event add that for NSManagedObject.class

- (void)excludeMappingForClass:(Class)class withKeys:(NSArray *)keys;
aryaxt commented 9 years ago

Example:

mappingProvider.excludeMappingForClass(NSManagedObjects.self, withKeys: ["faultingState", "deleted"])
poetmountain commented 9 years ago

@aryaxt If I'm understanding this correctly, this method would apply a global whitelist per-model? I think this probably addresses hoplaw's use-case, but in a case where you're sending a partial model via PATCH, and those model properties might be different every time (e.g. Message model where user can edit a 'title' or a 'body' property individually), a class-level whitelist wouldn't work. But perhaps that sort of dynamic model filtering isn't worth putting into the lib.

aryaxt commented 9 years ago

Yeah, feels like it would be easier to manually generate a dictionary, versus using the library with a whitelist properties array. The feature I added is a static mapping feature