Realm is still in its development phase where it have its limitations but somehow after I’m getting more and more familiar with Realm, some essentials must have issues in Realm are still unavailable today (23May2015). Therefore at current stage I might need to use some outsider extension on Realm for my needs.

For my early post on Realm, please refer here.

Example table scheme:

person-table

 

Limitation 1:

Null value in data’s value will crash the app

Example data:

{
    "occupation": "teacher",
    "name": "john",
    "age":35,
     ...
    "curriculum": <null>, //Crashed here
    "parents name" <null>
}

Error: 

-[NSNull UTF8String]: unrecognized selector sent to instance 0x10712b4c0 
 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull UTF8String]: unrecognized selector sent to instance 0x10712b4c0'

The given defaultPropertyValues from Realm only effective if the return response does not have the key so it still does not solve the problem. This is a known issue from 2014 and Realm does not yet support setting nil for NSString properties. (here)

+ (NSDictionary *)defaultPropertyValues {
    return @{@"jobscope" : @"", @"classes": @"", @"accountno":@"", @"curriculum": @"", @"parentname": @""};
}

Solution:

1. Stackoverflow : Loop through the response and set the null value to empty string.

-(NSMutableDictionary *) removeNullFromDictionary:(NSDictionary *) originalDictionary{

NSArray *allKeysArray = [originalDictionary allKeys];
const NSMutableDictionary *replaced = [originalDictionary mutableCopy];
const id nul = [NSNull null];
const NSString *blank = @"";

for(NSString *key in allKeysArray) {

    const id object = [originalDictionary objectForKey:key];

    if(object == nil) {
        [replaced setObject:blank forKey:key];
    }
}
return [replaced copy];
}

I feel that this is not a intelligent solution if I have a lot of data(few thousands) and it will have to loop though this method for each one just to do a null check.

2. ARNRealmExtension

https://cocoapods.org/pods/ARNRealmExtension

This extension only helps to replace default value if you have many properties in table that needed to handle the default values. (Smile)

ARNRealmExtension

 

 

Limitation 2: 

Absence of data’s key will throw REALM exception

Example data:

{
    "occupation": "student",
    "name": "nicky",
    "age":10,
    "curriculum": "basketball", 
    "parents name" "xxx"
}

//No keys: account no, classes, job scope - crashed here

Error:

REALM
// FIXME: Add condition to check for Mixed once it can support a nil value.
        if (!value && prop.type != RLMPropertyTypeObject) {
            @throw RLMException([NSString stringWithFormat:@"No value or default value specified for property '%@' in '%@'",
                                 prop.name, schema.className]);
        }

 

Solution:

1. JSONExport (Realm supported)

https://github.com/Ahmed-Ali/JSONExport

This is a cool program where it will auto-generate the codes based on your response data.

Notes:

  1. There is still some fine-tuning efforts needed like primary key.
  2. For some data like 1 or 0, it generate it as Bool.
  3. You might want to have properties string for ID 0000123 so you will need to change it yourself.
  4. You need to add in the relationship between each table yourself.

jsonexport

 

for the method generated in implementation class by JSONExport

-(instancetype)initWithDictionary:(NSDictionary *)dictionary
{
    if(dictionary == nil || [dictionary isKindOfClass:[NSNull class]]){
        return nil;
    }
    self = [super init];
if(![dictionary[@"accountno"] isKindOfClass:[NSNull class]]){      
    self.urlOnSiFull = dictionary[@"accountno"] ?: @"" ;
}

...

//added underline workaround code to ensure no exception thrown.

Usage:

RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
    
    for(NSMutableDictionary *personDic in response){
        Person *person = [Person new];
        [person initWithDictionary: personDic];
        [realm addOrUpdateObject:person];
    }
[realm commitWriteTransaction];

 

Hope you’ll find your workaround on Realm as well.

Cheers 🙂

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s