3

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

Michael Alan Huff
  • 3,462
  • 3
  • 28
  • 44
valbu17
  • 4,034
  • 3
  • 30
  • 41

2 Answers2

5

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];
    }

    //...
}
uɥƃnɐʌuop
  • 14,022
  • 5
  • 58
  • 61
0

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.

Ari
  • 1,439
  • 10
  • 7
  • Hi, I tried your approach but, you can't add an object if it's empty. It throws an exception. But, I still tried doing it calling twice or everytime I was going to manipulate the content or store in the database within my functions.. as show in the picture that I just uploaded.. Thanks! @Ari – valbu17 Jul 30 '14 at 02:15