Question

I was browsing around looking for a solution to implement a small offline data storage in one of my apps which would be easy and quick to use. Anyways, I came across with Realm to do this. But, I'm getting a problem that everytime I launch my app the content in the database is null.

I do all the allocation and call the beginWriteTransaction method. Set my database variable value. Then, I add the object to realm and finally commitWriteTransaction.

So, I do an NSLog to see if the value is actually set properly which it is(after updating it within my app). But when I shut down my application or stopped and run it again in the xcode iphone5 simulator. I try to set in the viewDidLoad method the value from database to a global variable in my app. Which I perform a NSLog to check if the value is either in my database or the global variable but it's display as null, meaning that is not getting store/saved.

This is the code..

@interface iReceiptDataBase : RLMObject

@property NSString* receiptNo;

@end

RLM_ARRAY_TYPE(iReceiptDataBase)

@implementation iReceiptDataBase

@end

//******** View Controller Implementation ************

- (void)viewDidLoad {

    self.realm = [RLMRealm defaultRealm]; // property type RLMRealm
    [realm beginWriteTransaction];

    self.myDataBase = [[iReceiptDataBase alloc] init]; // property type iReceiptDataBase
    receiptNumber = [myDataBase.receiptNo intValue];

    NSLog(@"In my realm database(first call) -> %@", myDataBase.receiptNo);

    NSLog(@"In my local app(first call) -> %d", receiptNumber);

}

-(void)drawPDF:(NSString*)fName {

    receiptNumber += 1; // property type int

    myDataBase.receiptNo = [NSString stringWithFormat:@"%d", receiptNumber];

    NSLog(@"In my realm database(second call) -> %@", myDataBase.receiptNo);

}

- (void)viewWillDisappear:(BOOL)animated {

    [realm addObject:myDataBase];

    [realm commitWriteTransaction];

}

I will also take in consideration any other options to achieve this.. Thanks!

*****UPDATE!** This is what I get in my test, which I changed to do beginWriteTransaction and commitWriteTransaction in both methods, but still doesn't work. It gets the value that I provide within my app but when I access again it doesn't pull/fetch that value from the database if it was ever store..

Screenshot of Xcode 6 showing NSLog and part of the code

Was it helpful?

Solution

The problem with your realm object is that you are not querying realm for your object. Rather, you are only allocating a new iReciptDataBase object. You will first need to add a property to that object so that you will be able to query for it, something like databaseId shown here:

@interface iReceiptDatabase : RLMObject
@property NSString *receiptNo;
@property NSString *databaseId;
@end

@implementation iReceiptDatabase
@end

RLM_ARRAY_TYPE(iReceiptDatabase)

Then in your viewDidLoad, you first query the realm file for an existing object, then only after not finding it, you would allocate it:

- (void)viewDidLoad {
    [super viewDidLoad];

    RLMRealm *realm = [RLMRealm defaultRealm];
    iReceiptDatabase *myDatabase = [[iReceiptDatabase objectsWhere:@"databaseId = '1'"] firstObject];

    if(!myDatabase) {
        [realm beginWriteTransaction];
        myDatabase = [[iReceiptDatabase alloc] init];
        myDatabase.receiptNo = @"1";
        myDatabase.databaseId = @"1";
        [realm addObject:myDatabase];
        [realm commitWriteTransaction];
    }

    //...
}

OTHER TIPS

My guess would be viewWillDisappear is never being called. I would recommend committing your write transaction after each change to your data rather than leaving the transaction open as long as the view is visible - instead of adding the object at the end, you could change your other methods to commit the data:

- (void)viewDidLoad {

    self.realm = [RLMRealm defaultRealm]; // property type RLMRealm

    [realm beginWriteTransaction];
    self.myDataBase = [[iReceiptDataBase alloc] init]; // property type iReceiptDataBase
    [realm addObject:myDataBase];
    [realm commitWriteTransaction];

    receiptNumber = [myDataBase.receiptNo intValue];

    NSLog(@"In my realm database(first call) -> %@", myDataBase.receiptNo);
    NSLog(@"In my local app(first call) -> %d", receiptNumber);
}

-(void)drawPDF:(NSString*)fName {

    receiptNumber += 1; // property type int

    [realm beginWriteTransaction];
    myDataBase.receiptNo = [NSString stringWithFormat:@"%d", receiptNumber];
    [realm commitWriteTransaction];

    NSLog(@"In my realm database(second call) -> %@", myDataBase.receiptNo);
}

I would also consider storing receiptNo as an int on your data model.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top