简体   繁体   中英

Store and fetch NSMutableArray in Core Data

I would like to save the NSMutableArray to Core-Data when my application terminates/goes into background and I would like to load the NSMutableArray when my application launches/becomes active.

I don't have a very good understanding of Core-Data yet. This is my first time working with it. I've looked at a bunch of videos, tutorials, previous Stackoverflow questions and Apple's documentation. I think what I am trying to do falls under the Non-Standard Persistent Attributes chapter in Apple's Core-Data documentation.

I have set up an Entity called TableViewList and I have given it an attribute called List of type transformable.

Here is my AppDelegate.h and .m code. All advice would be wonderful.

AppDelegate.h

#import <UIKit/UIKit.h>
#import "TableViewController.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property(nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property(nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property(nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

-(NSString *) applicationDocumentsDirectory;    
@end

AppDelegate.m

#import <CoreData/CoreData.h>
#import "AppDelegate.h"
#import <UIKit/UIKit.h>

@interface AppDelegate ()

@end

@implementation AppDelegate
@synthesize managedObjectModel;
@synthesize managedObjectContext;
@synthesize persistentStoreCoordinator;
- (void)applicationDidEnterBackground:(UIApplication *)application {

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSManagedObject *newContact;
    newContact = [NSEntityDescription insertNewObjectForEntityForName:@"TableViewList" inManagedObjectContext:context];
    NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:ListArray];        
    [newContact setValue:arrayData forKey:@"list"];
    NSError *error = nil;        
    [context save:&error];


}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:[NSBundle allBundles]];
    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    NSURL *url = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent: @"App1.sqlite"];
    [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:nil];
    managedObjectContext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
    managedObjectContext.persistentStoreCoordinator = coordinator;


    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"TableViewList" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    NSError *error = nil;
    NSArray *result = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

    if (error) {
        NSLog(@"unable to execute fetch request");
        NSLog(@"%@, %@", error, error.localizedDescription);
    }
    else
        NSLog(@"%@",result);
}

The result array returns an empty array. I don't think I'm saving and fetching the array correctly. Thanks in advance for your help!

I used this link to implement NSCoding in my object.

OK there are several things to mention here:

  1. In applicationDidEnterBackground , the first half of the method configures a new managed object context that you never use. Since you then get a different managed object context from the app delegate, you don't the one you create here, so the code that creates a new context can be deleted. You probably also want to use the app delegate's context in applicationDidBecomeActive , though what you have isn't necessarily wrong.

  2. You don't ever save changes. You need to call save: on the managed object context to save data to the persistent store file.

  3. In order to use a transformable property, the data you're saving must conform to NSCoding (because Core Data doesn't know how to transform arbitrary classes, and NSCoding is how you tell it what to do). NSArray does, but it's also important that everything in the array also conforms. If your custom class does that, you're OK. If not, you'll need to fix that to save the array or find a different way to save your data.

  4. I don't believe that you're going to get a mutable array back, no matter what you do. Once you get saving and fetching working, you'll get an immutable array as the value of the list property. So you'll need to call mutableCopy if you need the array to be mutable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM