Jan
Jan

Reputation: 127

How to get values stored in iOS persistent sqlite database?

I have a iOS persistent sqlite database and I can not remove the stored data:

    #import "DB.h"
    #import 

    @interface DB ()
    {
        NSString* db_title;
        NSURL* db_store_url;
        NSURL* db_model_url;

        NSPersistentStoreCoordinator* db_persistent_store_coordinator;
        NSManagedObjectModel* db_managed_object_model;
        NSManagedObjectContext* db_managed_object_context;
        NSFetchedResultsController* db_fetched_results_controller;
        NSFetchRequest* db_fetch_request;
        NSEntityDescription* db_entity_description;
        NSSortDescriptor* db_sort_descriptor;
        NSArray* db_sort_descriptors;
    }
    @end

    @implementation DB

    -(instancetype)init
    {
        NSLog(@"[%s]", __FUNCTION__);

        self = [super init];

        db_title = @"AlarmButtons";
        db_store_url = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:@"AlarmButtons.sqlite"];
        db_model_url = [[NSBundle mainBundle] URLForResource:db_title withExtension:@"momd"];

        return self;
    }

    -(void) delete_database_file
    {
        NSLog(@"[%s]", __FUNCTION__);

        NSError* error;

        if(![[NSFileManager defaultManager] removeItemAtURL:db_store_url error:&error])
        {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        }
    }

    -(void) load_database_file
    {
        NSLog(@"[%s]", __FUNCTION__);

        NSError* error;

        NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

        db_managed_object_model = [[NSManagedObjectModel alloc] initWithContentsOfURL:db_model_url];

        db_persistent_store_coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:db_managed_object_model];

        if(![db_persistent_store_coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:db_store_url options:options error:&error])
        {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

            if(![[NSFileManager defaultManager] removeItemAtURL:db_store_url error:&error])
            {
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            }

            if(![db_persistent_store_coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:db_store_url options:nil error:&error])
            {
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            }
        }

        db_managed_object_context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [db_managed_object_context setPersistentStoreCoordinator:db_persistent_store_coordinator];

        db_fetch_request = [[NSFetchRequest alloc] init];
        db_entity_description = [NSEntityDescription entityForName:db_title inManagedObjectContext:db_managed_object_context];

        [db_fetch_request setEntity:db_entity_description];
        [db_fetch_request setFetchBatchSize:20];

        db_sort_descriptor = [[NSSortDescriptor alloc] initWithKey:@"register_id" ascending:YES];
        db_sort_descriptors = @[db_sort_descriptor];

        [db_fetch_request setSortDescriptors:db_sort_descriptors];

        db_fetched_results_controller = [[NSFetchedResultsController alloc] initWithFetchRequest:db_fetch_request managedObjectContext:db_managed_object_context sectionNameKeyPath:nil cacheName:@"Master"];

        if(![db_fetched_results_controller performFetch:&error])
        {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }

    }

    -(void) save
    {
        NSLog(@"[%s]", __FUNCTION__);

        NSError* error;

        if([db_managed_object_context hasChanges] && ![db_managed_object_context save:&error])
        {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }

    -(void) insert
    {
        NSLog(@"[%s]", __FUNCTION__);

        NSManagedObject* new_managed_object = [NSEntityDescription insertNewObjectForEntityForName:[[[db_fetched_results_controller fetchRequest] entity] name] inManagedObjectContext:db_managed_object_context];

        [new_managed_object setValue:@"1" forKey:@"register_id"];
        [new_managed_object setValue:@"2" forKey:@"button_id"];
        [new_managed_object setValue:@"3" forKey:@"server_id"];
        [new_managed_object setValue:@"4" forKey:@"password"];

        NSLog(@"+register_id: %@", [new_managed_object valueForKey:@"register_id"]);
        NSLog(@"+button_id: %@", [new_managed_object valueForKey:@"button_id"]);
        NSLog(@"+server_id: %@", [new_managed_object valueForKey:@"server_id"]);
        NSLog(@"+password: %@", [new_managed_object valueForKey:@"password"]);

        [self save];
    }

    -(int) count_entities
    {
        NSLog(@"[%s]", __FUNCTION__);

        NSError *error;
        NSUInteger count = [db_managed_object_context countForFetchRequest:db_fetch_request error:&error];
        if(count == NSNotFound) {
            NSLog(@"count: NSNotFound!");
            return 0;
        }
        else
        {
            NSLog(@"count: %d", count);        
        }
        return count;
    }

    -(void) remove
    {
        NSLog(@"[%s]", __FUNCTION__);
        [db_managed_object_context deleteObject:[db_fetched_results_controller objectAtIndexPath:[[NSIndexPath alloc] initWithIndex:0]]];
    }

    @end
    

[-[DB remove]] 2017-01-05 20:49:18.380089 App[422:55746] [error] error: NSFetchedResultsController: no object at index 2147483647 in section at index 0 2017-01-05 20:49:18.381024 App[422:55746] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'no object at index 2147483647 in section at index 0' * First throw call stack: (0x1d47ee07 0x1c6df077 0x1f3f8185 0xf9a55 0xf8485 0x224d7123 0x224d6d0f 0x2260fe09 0x2260fba5 0x2260fa13 0x226127f7 0x224e4f1b 0x2261442d 0x22613199 0x224eed2f 0x224eeaed 0x2258e6e9 0x2258df2d 0x2258db1f 0x2258da99 0x224d45d5 0x202fa109 0x202ee31f 0x202ee1af 0x2027ea6b 0x2029d035 0x2029dad3 0x1d43a485 0x1d438701 0x1d388093 0x1d387e81 0x225428c9 0x2253cf61 0xf9f57 0x1cb5250b) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

What I am missing? The data is obviously stored successful.

Upvotes: 1

Views: 55

Answers (1)

pbasdf
pbasdf

Reputation: 21536

You are constructing an indexPath of length 1; fetched results controllers require an indexPath of length 2 (to represent the section and row). Amend your remove method as follows:

-(void) remove
{
    NSLog(@"[%s]", __FUNCTION__);
    NSUInteger indexes[] = {0,0};
    NSIndexPath *ip = [NSIndexPath indexPathWithIndexes:indexes length:2];
    [db_managed_object_context deleteObject:[db_fetched_results_controller objectAtIndexPath:ip]];
}

As @TomHarrington points out in comments, you can also use:

    NSIndexPath *ip = [NSIndexPath indexPathForRow:0 inSection:0];

though you might also need to import UIKit for this to work.

Upvotes: 1

Related Questions