Exclude Data Members in Android and/or iOS

Is there any way to exclude a data member from a class that is being persisted by the Backendless Data Service? (Like a java annotation, for example.)
There are cases where there is information stored on the data object that I do not want persisted on the server and I cannot find a way to annotate or specify what is persisted and not persisted.

Hi Tim,

With Java you have the following options:

    For fields you can use the transient declaration. For Java bean properties you can use the @ExcludeProperty annotation as shown below:
[code] @ExcludeProperty( propertyName = "foo" ) public class FooBar { private Foo _foo; public void setFoo( Foo _foo ){this._foo = _foo;} public Foo getFoo() {return _foo;} }

[/code]

There is also a way to list multiple bean properties in a single annotation:

@ExcludeProperties( propertyNames = { "foo", "bar" } )

The @ExcludeProperty annotation is in the weborb.service.ExcludeProperty package.

I will find out about available options in our Obj-C support and will let you know.

Regards,
Mark

              The annotation worked great for Android. Is similar functionality possible in iOS? It would be ideal if the models on iOS and Android could mirror each other.

              Hi Tim,

              Unfortunately, there is no similar support for iOS. The recommended approach is to mark your field private and have public accessor methods (the Java bean style serialization does not apply in iOS).

              Regards,
              Mark

              Hi Mark,

              Sorry for waking up an old thread but I was in fact looking for an answer to that same question. Can you please elaborate on your answer, it’s not clear to me how to create private property in Objective-C since there is no such concept in the language.

              Thanks!

              Hi Emmanuel,

              Here is an example of the “private” property - ‘beacons’.

              Retailer.h:

              @interface Retailer : NSObject
              @property (nonatomic, strong) NSString *objectId;
              @property (nonatomic, strong) NSString *company;
              @property (nonatomic, strong) NSMutableDictionary *location;
              @end
              

              Retailer.m:

              @interface Retailer ()
              @property (nonatomic, strong) NSMutableDictionary *beacons;
              @end
              
              
              @implementation Retailer
              -(NSString *)description {
               return [NSString stringWithFormat:@"<Retailer> [%@] %@\nlocations:%@\nbeacons:%@", self.objectId, self.company, self.location, self.beacons];
              }
              @end
              

              The ‘beacons’ property is not being persisted by the Data Service.

              Regards,
              Slava

              Hi Slava,

              Unfortunately this doesn’t work. The “private” data member is still saved to the DB.
              I’ve tried with a NSString though, not a NSMutableDictionary, but I believe that in this case a new relation would be created to the table “beacon” in this case (depending on the type of objects you hold in the beacons variable".

              Thanks.

              Hi again,

              I’d like to share my (convoluted) solution for you to consider and improve on.

              Say I have a class called File as such:

              @interface File : NSObject
              
              
              @property (nonatomic, strong) NSString                      *mime;
              @property (nonatomic, strong) NSString                      *url;
              @property (nonatomic, strong) NSString                      *objectId;
              @property (nonatomic, strong) NSString                      *ownerId;
              @property (nonatomic, strong) NSDate                        *created;
              @property (nonatomic, strong) NSDate                        *updated;
              
              
              + (File *)fileWithName:(NSString *)name data:(NSData *)data;
              + (File *)fileWithName:(NSString *)name mime:(NSString *)mime data:(NSData *)data;
              
              
              - (NSString *)name;
              - (NSData *)getData;
              - (BOOL)isUploaded;
              - (void)upload:(void(^)(NSString *url))successBlock error:(void(^)(Fault *fault))errorBlock;
              
              
              @end
              

              I don’t want to store the ‘name’ and ‘data’ properties to the DB so I create a new class in the .m file called FileData:

              @interface FileData : NSObject
              
              
              @property (nonatomic, copy) NSString                        *name;
              @property (nonatomic, strong) NSData                        *data;
              @property (nonatomic, assign) BOOL                          uploaded;
              
              
              + (FileData *)fileData:(NSString *)name data:(NSData *)data;
              
              
              @end
              

              I also declare a static MapTable like so:

              static NSMapTable *fileData;
              

              Then in the implementation of class File I create the MapTable fileData and use it to store and retrieve the private data:

              
              @implementation File
              
              
              + (void)load {
                  static dispatch_once_t onceToken;
                  dispatch_once(&onceToken, ^{
                      fileData = [NSMapTable weakToStrongObjectsMapTable];
                  });
              }
              
              
              + (File *)fileWithName:(NSString *)name data:(NSData *)data {
                  return [self fileWithName:name mime:@"" data:data];
              }
              
              
              + (File *)fileWithName:(NSString *)name mime:(NSString *)mime data:(NSData *)data {
                  File *file = [File new];
                  if (file) {
                      FileLocalData *fileLocalData = [FileLocalData fileData:name data:data];
                      [fileData setObject:fileLocalData forKey:file];
                      file.mime = mime;
                  }
                  return file;
              }
              
              
              - (void)dealloc {
                  [fileData removeObjectForKey:self];
              }
              
              
              - (NSString *)name {
                  FileLocalData *fileLocalData = [fileData objectForKey:self];
                  return fileLocalData.name;
              }
              
              
              - (NSData *)getData {
                  FileLocalData *fileLocalData = [fileData objectForKey:self];
                  return fileLocalData.data;
              }
              
              
              - (BOOL)isUploaded {
                  FileLocalData *fileLocalData = [fileData objectForKey:self];
                  return fileLocalData ? fileLocalData.uploaded : YES;
              }
              
              
              - (void)upload:(void(^)(NSString *url))successBlock error:(void(^)(Fault *fault))errorBlock {
                  [backendless.fileService
                   upload:[self name]
                   content:[self getData]
                   response:^(BackendlessFile *file) {
                       successBlock(file.fileURL);
                   }
                   error:^(Fault *fault) {
                       errorBlock(fault);
                   }];
              }
              
              
              @end
              
              

              Hi Emmanuel,

              I think the simplest way to solve this issue is to use private variables instead properties. These variables can be set, changed or removed via the public methods.
              I’ve made the appropriate correction in my example:

              Retailer.h

              @interface Retailer : NSObject
              @property (nonatomic, strong) NSString *objectId;
              @property (nonatomic, strong) NSString *company;
              @property (nonatomic, strong) GeoPoint *location;
              @end
              

              Retailer.m

              @interface Retailer () {
              NSMutableArray *beacons;
              NSData *data;
              }
              @end
              
              @implementation Retailer
              -(NSString *)description {
              return [NSString stringWithFormat:@"<Retailer> [%@] %@\nlocation:%@\nbeacons:%@\ndata:%@", self.objectId, self.company, self.location, beacons, data];
              }
              @end
              

              Hi Slava,

              I see, I’ll try that, thanks!

              I try to figure out how to use this in swift.

              I want to build objects I can later convert to an object like MKAnnotations for the use in MKMapKit.

              Unfortunately the iOS SDK asks the server for the property that doesn’t exists on the table at backendless. So I want to ignore this property. Is there any workaround for swift?

              import Foundation 
               
              import MapKit 
               
               
               
               
              class Story: NSObject { 
               
               
               
                  dynamic var objectId: String? 
               
               
               
               // The story's title 
               
               dynamic var title: String? 
               
               
               
               // The text to a story written by the user 
               
               dynamic var text: String? 
               
               
               
               // The geopoint of this story 
               
               dynamic var location: GeoPoint? 
               
               
               
               
               
               // Relationships 
               
               
               
               // to-many: A story can have more than one category 
               
               dynamic var categories: [Category] = [] 
               
               
               
               // to-many: A story has one or more figures 
               
               dynamic var figures: [Figure] = [] 
               
               
               
               
               
               
               
              } 
               
               
               
               
              extension Story: MKAnnotation { 
               
               
               
               
               var coordinate: CLLocationCoordinate2D { 
               
               return CLLocationCoordinate2D(latitude: location?.longitude as! Double, longitude: location?.latitude as! Double) 
               
               } 
               
              }
              
              
              
              

              This is how it looks right now. The property to ignore is “coordinate” but needed in this class since it is required by MKAnnotation.

              Hi Lennart,

              is the goal to make sure the “coordinate” property is ignored when you save instances of Story on the server?

              Regards,
              Mark

              No I don’t wanna save it on the servers. It’s just a entity I need to build a view for on the App.