Excluding attributes from serialization

6 views
Skip to first unread message

pcrawfor

unread,
Mar 10, 2009, 8:31:47 PM3/10/09
to ObjectiveResource
Hey guys,

I was just wondering if you had a recommended way to exclude
attributes from serialization/deserialization. I am storing objects
locally and want to store some attributes that relate to local
interactions and are not part of the schema of our rails app.

I've done a bit of looking and I know you have the default exclusions
that get used for serialization and it looks like it might be possible
to override
- (NSString *)toXMLElementAs:(NSString *)rootName excludingInArray:
(NSArray *)exclusions

Just wanted to ask if this was recommended or if there is a way to
handle this better.

Thanks guys!

Paul

Josh Vickery

unread,
Mar 10, 2009, 8:46:45 PM3/10/09
to objectiv...@googlegroups.com
Hi Paul,

What you've described is exactly what we do in various cases. It's
perhaps not the nicest interface, and if you have thoughts on how to
improve it I would be very interested to hear about them.

Here is an example from a class that has an "isUploaded" attribute
that we track locally but don't want to send to the server:

- (NSString *)toXMLElementAs:(NSString *)rootName
excludingInArray:(NSArray *)exclusions withTranslations:(NSDictionary
*)keyTranslations {
NSMutableArray *newExclusions = [NSMutableArray arrayWithArray:exclusions];
[newExclusions addObject:@"isUploaded"];
return [super toXMLElementAs:@"request"
excludingInArray:newExclusions withTranslations:keyTranslations];
}

Another option that I've been considering is to offer a class method
that returns an array of properties that should not be (de)serialized.
Something like:

- (NSArray *)excludedPropertyNames {
return [NSArray arrayWithObject:@"isUploaded"];
}

I think it's quite a bit cleaner. What does everyone else think of it?

Josh

pcrawfor

unread,
Mar 11, 2009, 11:41:23 AM3/11/09
to ObjectiveResource
Hey Josh,

I was thinking along the lines of the second option. Last night I
tried out this approach:

Modifying the convertToRemoteExpectedType to add the result of a call
to exclusions to the default exclusions if the object responds to
exclusions.

- (NSString *)convertToRemoteExpectedType {
// exclude id , created_at , updated_at
NSArray *defaultExclusions = [NSArray arrayWithObjects:[self
getRemoteClassIdName],@"createdAt",@"updatedAt",nil];
// add the custom exclusions if the object implements the method
if([self respondsToSelector:@selector(exclusions)])
defaultExclusions = [defaultExclusions
arrayByAddingObjectsFromArray:[self exclusions]];

return [self performSelector:[[self class] getRemoteSerializeMethod]
withObject:defaultExclusions];
}

I added a base definition

- (NSArray *)exclusions
{
return nil;
}

To NSObject+ObjectiveResource as well so in my model classes I can
just define the exclusions function and return an array of any
excluded properties if there are any.

I think using the name excludedPropertyNames is better then exclusions
though.

How's that sound to you guys?


Paul

On Mar 10, 5:46 pm, Josh Vickery <vicke...@gmail.com> wrote:
> Hi Paul,
>
> What you've described is exactly what we do in various cases. It's
> perhaps not the nicest interface, and if you have thoughts on how to
> improve it I would be very interested to hear about them.
>
> Here is an example from a class that has an "isUploaded" attribute
> that we track locally but don't want to send to the server:
>
> - (NSString *)toXMLElementAs:(NSString *)rootName
> excludingInArray:(NSArray *)exclusions withTranslations:(NSDictionary
> *)keyTranslations {
> NSMutableArray *newExclusions = [NSMutableArray arrayWithArray:exclusions];
> [newExclusions addObject:@"isUploaded"];
> return [super toXMLElementAs:@"request"
> excludingInArray:newExclusions withTranslations:keyTranslations];
>
> }
>
> Another option that I've been considering is to offer a class method
> that returns an array of properties that should not be (de)serialized.
> Something like:
>
> - (NSArray *)excludedPropertyNames {
> return [NSArray arrayWithObject:@"isUploaded"];
>
> }
>
> I think it's quite a bit cleaner. What does everyone else think of it?
>
> Josh
>

pcrawfor

unread,
Mar 11, 2009, 11:46:48 AM3/11/09
to ObjectiveResource
Hey Josh,

I did something along the lines of the second option last night which
seems to work pretty well.

I modified convertToRemoteExpectedType to add the array of exclusions
for the current object.

- (NSString *)convertToRemoteExpectedType {
// exclude id , created_at , updated_at
NSArray *defaultExclusions = [NSArray arrayWithObjects:[self
getRemoteClassIdName],@"createdAt",@"updatedAt",nil];
// add the custom exclusions if the object implements the method
if([self respondsToSelector:@selector(exclusions)])
defaultExclusions = [defaultExclusions
arrayByAddingObjectsFromArray:[self exclusions]];

return [self performSelector:[[self class] getRemoteSerializeMethod]
withObject:defaultExclusions];
}

and added a base definition of exclusions to NSObject
+ObjectiveResource.m/.h

- (NSArray *)exclusions
{
return nil;
}

Then in my model subclasses I can just define:

- (NSArray *)exclusions
{
return [NSArray arrayWithObjects:@"localPropertyName", nil];
}

To exclude the local property from serialization.

I think the name excludedPropertyNames is better than exclusions
though, going to change it to that.

What you do guys think?

Paul

On Mar 10, 5:46 pm, Josh Vickery <vicke...@gmail.com> wrote:
> Hi Paul,
>
> What you've described is exactly what we do in various cases. It's
> perhaps not the nicest interface, and if you have thoughts on how to
> improve it I would be very interested to hear about them.
>
> Here is an example from a class that has an "isUploaded" attribute
> that we track locally but don't want to send to the server:
>
> - (NSString *)toXMLElementAs:(NSString *)rootName
> excludingInArray:(NSArray *)exclusions withTranslations:(NSDictionary
> *)keyTranslations {
> NSMutableArray *newExclusions = [NSMutableArray arrayWithArray:exclusions];
> [newExclusions addObject:@"isUploaded"];
> return [super toXMLElementAs:@"request"
> excludingInArray:newExclusions withTranslations:keyTranslations];
>
> }
>
> Another option that I've been considering is to offer a class method
> that returns an array of properties that should not be (de)serialized.
> Something like:
>
> - (NSArray *)excludedPropertyNames {
> return [NSArray arrayWithObject:@"isUploaded"];
>
> }
>
> I think it's quite a bit cleaner. What does everyone else think of it?
>
> Josh
>

pcrawfor

unread,
Mar 11, 2009, 11:47:53 AM3/11/09
to ObjectiveResource
Gah - stupid double post

Josh Vickery

unread,
Mar 12, 2009, 8:10:13 AM3/12/09
to objectiv...@googlegroups.com
On Wed, Mar 11, 2009 at 11:46 AM, pcrawfor <pcra...@gmail.com> wrote:

> - (NSString *)convertToRemoteExpectedType {
>        // exclude id , created_at , updated_at
>        NSArray  *defaultExclusions = [NSArray arrayWithObjects:[self
> getRemoteClassIdName],@"createdAt",@"updatedAt",nil];
>        // add the custom exclusions if the object implements the method
>  if([self respondsToSelector:@selector(exclusions)])
>    defaultExclusions = [defaultExclusions
> arrayByAddingObjectsFromArray:[self exclusions]];
>
>  return [self performSelector:[[self class] getRemoteSerializeMethod]
> withObject:defaultExclusions];
> }

This looks like a solid approach to me. I created a ticket on
lighthouse to track this:

http://yfactorial.lighthouseapp.com/projects/18393-objectiveresource/tickets/62-add-cleaner-property-exclusion-support

Do you think this should affect deserialization as well? Would it make
sense to have two separate methods to handle that? The current code
ignores remote attributes that are not present on the local classes,
perhaps that is sufficient?

Paul, do you use github? If so, if you fork the 1.1 branch and apply
your changes I can pull them in directly.

James Burka

unread,
Mar 12, 2009, 9:57:33 AM3/12/09
to objectiv...@googlegroups.com
Hey Paul,

That looks good the only thing I would do would have the method on the
category return the default exclusions and have the
convertToRemoteExpectedType pull the exclusions from that. That way
people if they choose can override the defaults. Something like
(untested but I think this should work)

(NSString *)convertToRemoteExpectedType {
return [self performSelector:[[self class] getRemoteSerializeMethod]
withObject:[self exclusions];
}

and added a base definition of exclusions to NSObject
+ObjectiveResource.m/.h

- (NSArray *)exclusions
{
return [NSArray arrayWithObjects:[self
getRemoteClassIdName],@"createdAt",@"updatedAt",nil];
}

Then in the models you could append:

- (NSArray *)exclusions
{
NSArray *newExclusions [NSArray
arrayWithObjects:@"propertyName",nil];
return [[super exclusions]
arrayByAddingObjectsFromArray:newExclusions];
}

Or override:

- (NSArray *)exclusions
{
return [NSArray arrayWithObjects:@"propertyName",nil];
}

James

pcrawfor

unread,
Mar 12, 2009, 7:13:10 PM3/12/09
to ObjectiveResource
Hey Josh,

I do use github I'll fork and add my changes and ping you once they
are in.

Yesterday I pulled in your ObjectiveRecord code to replace
sqlitepersistentobjects, its working great for me so far. I had to
make one minor change to get it running but I've also implemented the
count and countByCritera functions on SQLitePersistenObject are you
interested in pulling in changes on ObjectiveRecord? If so I'll fork
ObjectiveSync and add my ObjectiveRecord changes too.

Thanks,

Paul



On Mar 12, 5:10 am, Josh Vickery <vicke...@gmail.com> wrote:
> On Wed, Mar 11, 2009 at 11:46 AM, pcrawfor <pcraw...@gmail.com> wrote:
> > - (NSString *)convertToRemoteExpectedType {
> > // exclude id , created_at , updated_at
> > NSArray *defaultExclusions = [NSArray arrayWithObjects:[self
> > getRemoteClassIdName],@"createdAt",@"updatedAt",nil];
> > // add the custom exclusions if the object implements the method
> > if([self respondsToSelector:@selector(exclusions)])
> > defaultExclusions = [defaultExclusions
> > arrayByAddingObjectsFromArray:[self exclusions]];
>
> > return [self performSelector:[[self class] getRemoteSerializeMethod]
> > withObject:defaultExclusions];
> > }
>
> This looks like a solid approach to me. I created a ticket on
> lighthouse to track this:
>
> http://yfactorial.lighthouseapp.com/projects/18393-objectiveresource/...

Josh Vickery

unread,
Mar 12, 2009, 7:19:19 PM3/12/09
to objectiv...@googlegroups.com
> I do use github I'll fork and add my changes and ping you once they
> are in.
Great. What did you think of Jame's suggestion? I think it's a good one.

> Yesterday I pulled in your ObjectiveRecord code to replace
> sqlitepersistentobjects, its working great for me so far.  I had to
> make one minor change to get it running but I've also implemented the
> count and countByCritera functions on SQLitePersistenObject are you
> interested in pulling in changes on ObjectiveRecord?  If so I'll fork
> ObjectiveSync and add my ObjectiveRecord changes too.

I'm very interested, please fork.

Abhijeet Kumar

unread,
Mar 12, 2009, 7:52:17 PM3/12/09
to objectiv...@googlegroups.com
Hello Paul,

I would like to play with objectiverecord but could not find the
repository. I am using SQLitePersistentObjects for the time being but
would love to port to ObjectiveRecord.

http://github.com/yfactorial/objectiverecord/tree/master has it empty?

Thanks,
Kumar

Josh Vickery

unread,
Mar 12, 2009, 7:58:23 PM3/12/09
to objectiv...@googlegroups.com
I'm not Paul, but I can point you in the right direction.

First off, ObjectiveRecord isn't really much a project, it's a fork of
sqlitepersistentobjects that I made to work with the ObjectiveSync
project. They are both very much a work in progress, so
ObjectiveRecord currently lives inside the ObjectiveSync project:
http://github.com/yfactorial/objectivesync/tree/040d622d5a64895ca0ae67352d00e49dc9961a99/external_libs/ObjectiveRecord

Josh

A. K.

unread,
Mar 12, 2009, 8:01:11 PM3/12/09
to objectiv...@googlegroups.com
Thanks, Josh,

Again, thanks much for this! I just started using ObjectiveResource
and it had made my life much easier. I will play with ObjectiveSync
and see if I can contribute in any way.

Kumar

pcrawfor

unread,
Mar 13, 2009, 7:44:24 PM3/13/09
to ObjectiveResource
On Mar 12, 4:19 pm, Josh Vickery <vicke...@gmail.com> wrote:
> > I do use github I'll fork and add my changes and ping you once they
> > are in.
>
> Great. What did you think of Jame's suggestion? I think it's a good one.
>

I agree with Jame's suggestion I just forked the project so I'll try
adding that to my implementation and see how it works.

pcrawfor

unread,
Mar 13, 2009, 8:31:41 PM3/13/09
to ObjectiveResource

Josh Vickery

unread,
Mar 14, 2009, 11:16:12 AM3/14/09
to objectiv...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages