3

I have a simple scenario where I want to parse a User model from Json with Mantle and persist it to a realm database:

In order to use the Mantle library, the model interface must extend the MTLModel class like this:

@interface User: MTLModel<MTLJSONSerializing>
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *email;
@end

and in order to persist that model in realm, I have to declare a second interface that extends from RLMObject:

@interface RLMUser:RLMObject
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *email;
@end

As you see I had to implement another type of the User class because I have to extend RLMObject.

is there a way to avoid this kind of duplication?

Mina Wissa
  • 10,923
  • 13
  • 90
  • 158
  • 1
    Alternatively, it may be enough to conform to the `MTLModel` protocol but you would have to implement a lot of the `MTLModel` class functionality. – David Snabel-Caunt Jun 01 '16 at 11:06
  • Thanks, that seems a proper implementation, I'll give it a try. I'll even consider dropping both frameworks and using anything else with better implemenations. – Mina Wissa Jun 01 '16 at 12:41
  • @MinaSamy Did you find using the `` protocol to work? Would love to hear how it turned out – beebcon Feb 21 '17 at 00:37
  • 1
    @beebcon Hi, we found that implementing the protocol for each type would take a lot of effort, we ended using the Realm-Json library, it basically adds the Mantle functionality to the the RLMObject through categories, so you end by extending a single object which is both Realm and Mantle object. https://github.com/matthewcheok/Realm-JSON – Mina Wissa Feb 21 '17 at 10:37
  • @MinaSamy Thanks, I think that's the way to go too - I notice is restricted to Realm < v1 which sucks but might be able to find a fork supporting Realm ~2.4 – beebcon Feb 22 '17 at 16:19
  • For those interested, I made my own fork to support modern Realm versions via `s.dependency 'Realm', '~> 2'` https://github.com/bradgmueller/Realm-JSON seems to be all good – beebcon Feb 22 '17 at 16:39

2 Answers2

3

Hmmm, you COULD try creating a single class that inherits from both classes down a chain as long as RLMObject is the highest superclass (eg User > MTLModel > RLMObject) and seeing if that works. If MTLModel only works on its data through key-path values, Realm might be able to handle working with it like that.

But in all honesty, if you want to ensure that both classes behave properly as intended, it's probably best not to mix them, and simply copy the data across them when needed.

Thankfully, because RLMObject instances exposes all of the properties it persists through an RLMObjectSchema object, you don't need to manually copy each property manually, and can do it with a pretty minimal amount of code:

User *mantleUser = ...;
RLMUser *realmUser = ...;

// Loop through each persisted property in the Realm object and 
// copy the data from the equivalent Mantle property to it
for (RLMProperty *property in realmUser.objectSchema.properties) {
   id mantleValue = [mantleUser valueForKey:property.name];
   [realmUser setValue:mantleValue forKey:property.name];
}
TiM
  • 15,812
  • 4
  • 51
  • 79
  • Thanks, The multiple inheritance is not feasible, your suggestion to copy to the properties is a way better. let me ask you if there is a way to define the realm object schema itself rather than defining properties to the Realm object? – Mina Wissa May 27 '16 at 12:21
0

Base on the idea of using the protocol, I created a super class (gist here):

@interface ModelBase : RLMObject <MTLJSONSerializing, MTLModel>

Then as @David Snabel-Caunt said, I ended up implementing some functions of the MTLModel class (copy-paste from MTLModel.m).

Finally to use it, you just need to subclass it.

Siyu
  • 11,187
  • 4
  • 43
  • 55