Coredata database prepopulation is not filled - ios

I'm trying to prepopulate a coredata database from a sqlite file, but I don't understand why the database is not filled. My sqlite file is properly filled with all the data I need and added in the bundle ressources.
Here the persistentStoreCoordinator method int the AppDelegate :
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (persistentStoreCoordinator != nil)
{
return persistentStoreCoordinator;
}
NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingString:#"MyApp.db"];
NSError *error = nil;
NSFileManager *fm = [NSFileManager defaultManager];
if (![fm fileExistsAtPath:storePath])
{
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:#"MyApp" ofType:#"db"];
if (defaultStorePath)
{
[fm copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error])
{
NSLog(#"Unresolved error : %#: %#", error, [error userInfo]);
abort();
}
return persistentStoreCoordinator;
}
In the view controller, I try to fetch the entries but it seems enter code hereempty :
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
initWithEntityName:#"Type_textimage_4text"];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *description = [NSEntityDescription entityForName:#"Type_textimage_4text" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:description];
NSMutableArray *questions = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
NSLog(#"question : %#", questions);
I probably missed something but I don't find what. Anyone can help me please ?

In answer to the coment above, I'm adding the AppDelegate.m file of one App which includes a prepopulated sqlite database. To do that I selected "Use Core Data" when I created the project on xcode. Although it works for me, I believe it is now a better praxis to use NSDocument for this kind of applications. One of the advantages is that the project is already on a good track to be iCloud compatible. I haven't done that yet, so I'm speaking only from what I've read/seen.
//
// AppDelegate.m
//
//
//
#import "AppDelegate.h"
#import "MainView.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize managedObjectContext = __managedObjectContext;
#synthesize managedObjectModel = __managedObjectModel;
#synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *navViewController = (UINavigationController *)self.window.rootViewController;
MainView *main=[[navViewController viewControllers]objectAtIndex:0];
main.managedObjectContext=self.managedObjectContext;
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
- (void)applicationWillTerminate:(UIApplication *)application
{
}
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
}
#pragma mark - Core Data stack
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil) {
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
__managedObjectContext = [[NSManagedObjectContext alloc] init];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return __managedObjectContext;
}
// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
- (NSManagedObjectModel *)managedObjectModel
{
if (__managedObjectModel != nil) {
return __managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"Solvents" withExtension:#"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
- (NSString *)applicationDocumentsDirectoryString {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"Solvents.sqlite"];
NSString *storePath = [[self applicationDocumentsDirectoryString] stringByAppendingPathComponent: #"Solvents.sqlite"];
//NSLog(#"store path %#", storePath);
//NSLog(#"store URL%#", storeURL );
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:storePath ]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:#"Solvents" ofType:#"sqlite"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return __persistentStoreCoordinator;
}
#pragma mark - Application's Documents directory
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
#end

Related

NSPersistentStoreCoordinator has no persistent stores (can't open)

I have my CoreDataManager Class and initialising Core Data Objects.
But when below piece of code runs it throws and error and cause crashing the app.
NSPersistentStoreCoordinator has no persistent stores (can't open)
When i debug the code it shows that the persistentStore object is actually nil.
Here is My CoreDataManager.m file
+ (id)sharedInstance {
static CoreDataManager *instance_ = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance_ = [[self alloc] init];
});
return instance_;
}
- (NSManagedObjectContext *)managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [NSManagedObjectContext new];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
managedObjectModel = [[NSManagedObjectModel alloc]initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:#"AppTutor" withExtension:#"momd"]];
return managedObjectModel;
}
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSString *documentsStorePath =
[[[self applicationDocumentsDirectory] path] stringByAppendingPathComponent:#"AppTutor.sqlite"];
// if the expected store doesn't exist, copy the default store
if (![[NSFileManager defaultManager] fileExistsAtPath:documentsStorePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:#"AppTutor" ofType:#"sqlite"];
if (defaultStorePath) {
[[NSFileManager defaultManager] copyItemAtPath:defaultStorePath toPath:documentsStorePath error:NULL];
}
}
persistentStoreCoordinator =
[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
// add the default store to our coordinator
NSError *error;
NSURL *defaultStoreURL = [NSURL fileURLWithPath:documentsStorePath];
NSPersistentStore *store = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:defaultStoreURL
options:nil
error:&error];
if (store == nil) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
// setup and add the user's store to our coordinator
NSURL *userStoreURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"AppTutor.sqlite"];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:userStoreURL
options:nil
error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
return persistentStoreCoordinator;
}
Can you try to add these options to the addPersistentStoreWithType function?
NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:userStoreURL
options:options
error:&error]

Use two separate data model with coredata?

In my app I am using sqlite database and core data for showing data in database and every thing ok.
I want user to be able to add photo in document directory of app, so I defined two model for app.
I used this link http://blog.atwam.com/blog/2012/05/11/multiple-persistent-stores-and-seed-data-with-core-data/
and also PhotoLocations from Apple sample code(https://developer.apple.com/library/ios/samplecode/PhotoLocations/Introduction/Intro.html) for add photo functionality.
Showing data from sql is fine but when I add another model to app and manipulate AppDelegate , app crashes.
I don't want to use MagicalRecord because I am more than half way with core data .
Here is my original AppDelegate:
// AppDelegate.m
// iranbirds
//
// Created by Mehdi on 7/31/16.
// Copyright © 2016 Mehdi. All rights reserved.
//
#import "AppDelegate.h"
#import "BirdsTableViewController.h"
#import "GeneralViewController.h"
#import "FavoriteTableViewController.h"
#import "MapViewController.h"
#import "MoreViewController.h"
//#import "Bird.h" //maybe delete
#import "BirdInfo.h"
#import "BirdImage.h"
#import "Favorite.h"
#import <CoreData/CoreData.h>
#interface AppDelegate () //class extension
#property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, strong) NSManagedObjectModel *managedObjectModel;
#property (nonatomic, strong) NSPersistentStoreCoordinator *persistentStoreCoordinator;
#property (nonatomic, strong) NSArray *fetchedObjects;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UINavigationController *naviController = (UINavigationController *)tabBarController.viewControllers[0];
naviController = (UINavigationController *)tabBarController.viewControllers[0];
BirdsTableViewController *catalogViewController = (BirdsTableViewController *)[naviController topViewController];
// catalogViewController.managedojbectContext = self.managedObjectContext;
//pass managed context to species view controller
naviController = (UINavigationController *)tabBarController.viewControllers[0];
MapViewController *mapViewController = (MapViewController *)[naviController topViewController];
mapViewController.managedOjbectContext = self.managedObjectContext;
naviController = (UINavigationController *)tabBarController.viewControllers[0];
FavoriteTableViewController *favoriteViewcontroller = (FavoriteTableViewController *)[naviController topViewController];
favoriteViewcontroller.managedOjbectContext = self.managedObjectContext;
//pass managed context view controller
naviController = (UINavigationController *)tabBarController.viewControllers[0];
MoreViewController *moreViewController = (MoreViewController *)[naviController topViewController];
moreViewController.managedOjbectContext = self.managedObjectContext;
//pass managed context view controller
naviController = (UINavigationController *)tabBarController.viewControllers[0];
APLViewController *aplViewController = (APLViewController *)[naviController topViewController];
aplViewController.managedOjbectContext = self.managedObjectContext;
return YES;
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
#pragma mark - Core Data stack
- (NSManagedObjectModel *)managedObjectModel {
if (_managedObjectModel == nil) {
NSString *modelPath = [[NSBundle mainBundle] pathForResource:#"TaxonModel" ofType:#"mom"];
NSURL *modelUrl = [NSURL fileURLWithPath:modelPath];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl];
}
return _managedObjectModel;
}
- (NSString *)documentsDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths lastObject];
//NSLog(#"document directory: %#", documentsDirectory);
return documentsDirectory;
}
- (NSString *)dataStorePath
{
return [[self documentsDirectory] stringByAppendingPathComponent:#"DataStore.sqlite"];
}
/**
Returns the persistent store coordinator for the application.
If the coordinator doesn't already exist, it is created and the application's store added to it.
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
if (_persistentStoreCoordinator == nil) {
//if the expected store doesn't exist, copy the default store from main bundle
if (![[NSFileManager defaultManager] fileExistsAtPath:[self dataStorePath]]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:#"DataStore" ofType:#"sqlite"]; // we construct a path to our database file We’re storing the database in our application’s bundle,o we use the pathForResource method to obtain the path.
if (defaultStorePath) {
[[NSFileManager defaultManager] copyItemAtPath:defaultStorePath toPath:[self dataStorePath] error:NULL];
}
}
NSURL *storeUrl = [NSURL fileURLWithPath:[self dataStorePath]];
// NSURL *storeUrl= [[self applicationDirectory] URLByAppendingPathComponent:#"Card.sqlite"];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
NSError *error;
//NSDictionary *options = #{NSSQLitePragmasOption:#{#"journal_mode":#"DELETE"}};
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeUrl
options:nil
error:&error]) {
//NSLog(#"Error adding persistent store %#, %#", error, [error userInfo]);
abort();
}
}
[self addSkipBackupAttributeToItemAtPath:[self dataStorePath]];
return _persistentStoreCoordinator;
}
- (BOOL)addSkipBackupAttributeToItemAtPath:(NSString *) filePathString
{
NSURL* URL= [NSURL fileURLWithPath:filePathString];
assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);
NSError *error = nil;
BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
forKey: NSURLIsExcludedFromBackupKey error: &error];
if(!success){
NSLog(#"Error excluding %# from backup %#", [URL lastPathComponent], error);
}
//NSLog(#"Added %#",[NSNumber numberWithBool: success]);
return success;
}
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext == nil) {
NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator;
if (coordinator !=nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
}
return _managedObjectContext;
}
- (void)preloadData {
NSString *path = [[NSBundle mainBundle] pathForResource:#"acachecklist" ofType:#"txt"];
NSError *error;
NSString *allBirds = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (allBirds == nil) {
//NSLog(#"Error reading file: %#",[error localizedDescription]);
}
NSArray *lines=[allBirds componentsSeparatedByString:#"\n"];
unsigned long count = [lines count];
NSArray *bird;
for(int i=0;i<count;i++) {
bird=[[lines objectAtIndex:i] componentsSeparatedByString:#"\t"];
BirdInfo *info = [NSEntityDescription insertNewObjectForEntityForName:#"BirdInfo"
inManagedObjectContext:self.managedObjectContext];
BirdImage *imageObj = [NSEntityDescription insertNewObjectForEntityForName:#"BirdImage"
inManagedObjectContext:self.managedObjectContext];
UIImage *tempImage = [UIImage imageNamed:#"Placeholder"];
imageObj.image = UIImageJPEGRepresentation(tempImage,1);
info.category = [bird objectAtIndex:0];
info.com_name = [bird objectAtIndex:1];
info.sci_name = [bird objectAtIndex:2];
//info.taxon_id = [bird objectAtIndex:2];
info.thumbnailImage = imageObj;
NSError *error;
if (![self.managedObjectContext save:&error]) {
//NSLog(#"Error: %#", error);
abort();
}
}
}
- (void)preLoadSpecies
{
NSManagedObjectContext *privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
privateContext.persistentStoreCoordinator = self.managedObjectContext.persistentStoreCoordinator;
NSEntityDescription *entity = [NSEntityDescription insertNewObjectForEntityForName:#"BirdInfo"
inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *allSpeciesRequest = [[NSFetchRequest alloc] init];
[allSpeciesRequest setEntity:entity];
[privateContext performBlock:^{
NSError *error;
self.fetchedObjects = [privateContext executeFetchRequest:allSpeciesRequest error:&error];
if (error) {
//NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}];
}
#end
AppDelegate after edit:
#import "AppDelegate.h"
#import "BirdsTableViewController.h"
#import "GeneralViewController.h"
#import "FavoriteTableViewController.h"
#import "MapViewController.h"
#import "MoreViewController.h"
//#import "Bird.h" //maybe delete
#import "BirdInfo.h"
#import "BirdImage.h"
#import "Favorite.h"
#import <CoreData/CoreData.h>
#import "APLViewController.h"
#interface AppDelegate () //class extension
#property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, strong) NSManagedObjectModel *managedObjectModel;
#property (nonatomic, strong) NSPersistentStoreCoordinator *persistentStoreCoordinator;
#property (nonatomic, strong) NSArray *fetchedObjects;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UINavigationController *naviController = (UINavigationController *)tabBarController.viewControllers[0];
naviController = (UINavigationController *)tabBarController.viewControllers[0];
BirdsTableViewController *catalogViewController = (BirdsTableViewController *)[naviController topViewController];
// catalogViewController.managedojbectContext = self.managedObjectContext;
//pass managed context to species view controller
naviController = (UINavigationController *)tabBarController.viewControllers[0];
MapViewController *mapViewController = (MapViewController *)[naviController topViewController];
mapViewController.managedOjbectContext = self.managedObjectContext;
naviController = (UINavigationController *)tabBarController.viewControllers[0];
FavoriteTableViewController *favoriteViewcontroller = (FavoriteTableViewController *)[naviController topViewController];
favoriteViewcontroller.managedOjbectContext = self.managedObjectContext;
//pass managed context view controller
naviController = (UINavigationController *)tabBarController.viewControllers[0];
APLViewController *aplViewController = (APLViewController *)[naviController topViewController];
aplViewController.managedOjbectContext = self.managedObjectContext;
/*
//[self preloadData]; //preload birds info into core data
// UITabBarController *tabBarController ;
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
//pass managed context to first view controller
UINavigationController *naviController = (UINavigationController *)tabBarController.viewControllers[0];
BirdsTableViewController *birdsTableViewController = (BirdsTableViewController *)[naviController topViewController];
birdsTableViewController.managedOjbectContext = self.managedObjectContext;
//pass managed context to nearby view controller
naviController = (UINavigationController *)tabBarController.viewControllers[1];
GeneralViewController *generalViewController = (GeneralViewController *)[naviController topViewController];
generalViewController.managedOjbectContext = self.managedObjectContext;
//pass managed context to species view controller
naviController = (UINavigationController *)tabBarController.viewControllers[2];
SpeciesViewController *catalogViewController = (SpeciesViewController *)[naviController topViewController];
catalogViewController.managedOjbectContext = self.managedObjectContext;
//pass managed context to favorite view controller
naviController = (UINavigationController *)tabBarController.viewControllers[3];
FavoritesViewController *favoriteViewcontroller = (FavoritesViewController *)[naviController topViewController];
favoriteViewcontroller.managedOjbectContext = self.managedObjectContext;
UIColor* navColor = [UIColor colorWithRed:0.175f green:0.458f blue:0.831f alpha:1.0f];
[[UINavigationBar appearance] setBarTintColor:navColor];
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
[[UINavigationBar appearance] setTitleTextAttributes:#{NSForegroundColorAttributeName: [UIColor whiteColor]}];
//UIColor *barColor = [UIColor colorWithRed:0.012 green:0.286 blue:0.553 alpha:1.0];
[tabBarController.tabBar setTintColor:navColor];
//[self preLoadSpecies];
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
//set tab bar item selected images;
NSArray *array = tabBarController.tabBar.items;
((UITabBarItem *)array[2]).selectedImage = [UIImage imageNamed:#"Pelican Filled"];
((UITabBarItem *)array[0]).selectedImage = [UIImage imageNamed:#"Log Cabin Filled"];
((UITabBarItem *)array[1]).selectedImage = [UIImage imageNamed:#"Binoculars Filled"];
((UITabBarItem *)array[3]).selectedImage = [UIImage imageNamed:#"Like Filled"];
//pass managed context to general view controller
UINavigationController *naviController = (UINavigationController *)tabBarController.viewControllers[0];
GeneralViewController *Genralviewcontroler = (GeneralViewController *)[naviController topViewController];
Genralviewcontroler.managedOjbectContext = self.managedObjectContext;
[window addSubview:_navController.view];
*/
//set tab bar item selected images;
NSArray *array = tabBarController.tabBar.items;
//((UITabBarItem *)array[2]).selectedImage = [UIImage imageNamed:#"Pelican Filled"];
((UITabBarItem *)array[0]).selectedImage = [UIImage imageNamed:#"Log Cabin Filled"];
//((UITabBarItem *)array[1]).selectedImage = [UIImage imageNamed:#"Falcon Filled"];
((UITabBarItem *)array[2]).selectedImage = [UIImage imageNamed:#"Like Filled"];
return YES;
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
#pragma mark - Core Data stack
- (NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *uModelURL = [[NSBundle mainBundle] URLForResource:#"Locations" withExtension:#"momd"];
NSManagedObjectModel* uModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:uModelURL];
NSURL *pdModelURL = [[NSBundle mainBundle] URLForResource:#"TaxonModel" withExtension:#"mom"];
NSManagedObjectModel* pdModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:pdModelURL];
_managedObjectModel = [NSManagedObjectModel modelByMergingModels:[NSArray arrayWithObjects:uModel, pdModel, nil]];
return _managedObjectModel;
}
- (NSString *)documentsDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths lastObject];
//NSLog(#"document directory: %#", documentsDirectory);
return documentsDirectory;
}
- (NSString *)dataStorePath
{
return [[self documentsDirectory] stringByAppendingPathComponent:#"DataStore.sqlite"];
}
/**
Returns the persistent store coordinator for the application.
If the coordinator doesn't already exist, it is created and the application's store added to it.
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
[self addSeedDataToCoordinator:_persistentStoreCoordinator];
NSURL* userURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"UserData.sqlite"];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
/*
// Allow inferred migration from the original version of the application.
NSDictionary *options = #{ NSMigratePersistentStoresAutomaticallyOption : #YES, NSInferMappingModelAutomaticallyOption : #YES };
*/
// Note that we use our UserConf here
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:#"UserConf" URL:userURL options:nil error:&error])
{
NSLog(#"Error %#",error);
}
[self addSkipBackupAttributeToItemAtPath:[self dataStorePath]]; // *******i added*******
return _persistentStoreCoordinator;
}
- (void) addSeedDataToCoordinator:(NSPersistentStoreCoordinator *)storeCoordinator
{
// Our destination url, writtable. Make sure this is in Library/Cache if you don't want iCloud to backup this.
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"DataStore.sqlite"];
NSError *error = nil; //************ i define
//NSURL* adURL;//********************i define
// If we don't have our migrated store, prepare it
if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]])
{
// Our source url should come from a download, but let's use our bundle for debug purposes in the simulator
NSURL *baseURL = [[NSBundle mainBundle] URLForResource:#"DataStore" withExtension:#"sqlite"];
// [[NSFileManager defaultManager] copyItemAtPath:baseURL toPath:[self dataStorePath] error:NULL]; ///##########this line
// [NSFileManager defaultManager]copyItemAtPath:<#(nonnull NSString *)#> toPath:<#(nonnull NSString *)#> error:NULL];
[[NSFileManager defaultManager]contentsAtPath:[self dataStorePath]]; // I ADD THIS LINE
// Create one coordinator that just migrates, but isn't used.
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
nil];
// This will just handle the migration, without any configuration or else ...
NSPersistentStore* tmpStore = [storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];
// And remove it !
[storeCoordinator removePersistentStore:tmpStore error:&error];
}
// And now add the coordinator with the correct 'PostCodesConf' configuration, in readonly mode
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSReadOnlyPersistentStoreOption, nil];
[storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:#"PostCodesConf" URL:storeURL options:options error:&error];
}
- (BOOL)addSkipBackupAttributeToItemAtPath:(NSString *) filePathString
{
NSURL* URL= [NSURL fileURLWithPath:filePathString];
assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);
NSError *error = nil;
BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
forKey: NSURLIsExcludedFromBackupKey error: &error];
if(!success){
NSLog(#"Error excluding %# from backup %#", [URL lastPathComponent], error);
}
//NSLog(#"Added %#",[NSNumber numberWithBool: success]);
return success;
}
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext == nil) {
NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator;
if (coordinator !=nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
}
return _managedObjectContext;
}
- (void)preloadData {
NSString *path = [[NSBundle mainBundle] pathForResource:#"acachecklist" ofType:#"txt"];
NSError *error;
NSString *allBirds = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (allBirds == nil) {
//NSLog(#"Error reading file: %#",[error localizedDescription]);
}
NSArray *lines=[allBirds componentsSeparatedByString:#"\n"];
unsigned long count = [lines count];
NSArray *bird;
for(int i=0;i<count;i++) {
bird=[[lines objectAtIndex:i] componentsSeparatedByString:#"\t"];
BirdInfo *info = [NSEntityDescription insertNewObjectForEntityForName:#"BirdInfo"
inManagedObjectContext:self.managedObjectContext];
BirdImage *imageObj = [NSEntityDescription insertNewObjectForEntityForName:#"BirdImage"
inManagedObjectContext:self.managedObjectContext];
UIImage *tempImage = [UIImage imageNamed:#"Placeholder"];
imageObj.image = UIImageJPEGRepresentation(tempImage,1);
info.category = [bird objectAtIndex:0];
info.com_name = [bird objectAtIndex:1];
info.sci_name = [bird objectAtIndex:2];
//info.taxon_id = [bird objectAtIndex:2];
info.thumbnailImage = imageObj;
NSError *error;
if (![self.managedObjectContext save:&error]) {
//NSLog(#"Error: %#", error);
abort();
}
}
}
- (void)preLoadSpecies
{
NSManagedObjectContext *privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
privateContext.persistentStoreCoordinator = self.managedObjectContext.persistentStoreCoordinator;
NSEntityDescription *entity = [NSEntityDescription insertNewObjectForEntityForName:#"BirdInfo"
inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *allSpeciesRequest = [[NSFetchRequest alloc] init];
[allSpeciesRequest setEntity:entity];
[privateContext performBlock:^{
NSError *error;
self.fetchedObjects = [privateContext executeFetchRequest:allSpeciesRequest error:&error];
if (error) {
//NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}];
}
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
#end
App crashes when I want to load data in first view controller with below logs:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'BirdInfo''

Core Data addPersistentStoreWithType return nil, but error is nil too

I'm creating a NSPersistentStore with the code below.
NSPersistentStore * pc = [persistentCoordinator
addPersistentStoreWithType:EncryptedStoreType
configuration:nil
URL:databaseURL
options:options
error:error];
if (*error)
{
NSLog(#"Unable to add persistent store.");
NSLog(#"Error: %#\n%#\n%#", *error, [*error userInfo], [*error localizedDescription]);
}
The value of options is
{
EncryptedStore = SQLite;
EncryptedStoreDatabaseLocation =
"file:///var/mobile/Containers/Data/Application/0C27F628-3FF0-467F-8EF1-5974EBBD3620/Documents/DBEncrypted.sqlite";
EncryptedStorePassphrase = "xxxxxxxxredactedxxxxxxx";
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;
NSSQLitePragmasOption = {
synchronous = OFF;
};
}
At this point *error is nil and pc is nil too.
According to Apple's documentation if the function returns nil should be an error. Does anyone saw it before?
The EncryptedStoreType is from https://github.com/project-imas/encrypted-core-data
The error only happens if we are migrating the Data Store
EDIT:
Full code of method:
+ (NSPersistentStoreCoordinator *)makeStoreWithOptions:(NSDictionary *)options managedObjectModel:(NSManagedObjectModel *)objModel error:(NSError *__autoreleasing *)error
{
NSPersistentStoreCoordinator * persistentCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:objModel];
// NSString* appSupportDir = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) objectAtIndex:0];
BOOL backup = YES;
NSURL *databaseURL;
id dburl = [options objectForKey:EncryptedStoreDatabaseLocation];
if(dburl != nil) {
if ([dburl isKindOfClass:[NSString class]]){
databaseURL = [NSURL URLWithString:[options objectForKey:EncryptedStoreDatabaseLocation]];
backup = NO;
}
else if ([dburl isKindOfClass:[NSURL class]]){
databaseURL = dburl;
backup = NO;
}
}
if (backup){
NSString *dbNameKey = (__bridge NSString *)kCFBundleNameKey;
NSString *dbName = NSBundle.mainBundle.infoDictionary[dbNameKey];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *applicationSupportURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
[fileManager createDirectoryAtURL:applicationSupportURL withIntermediateDirectories:NO attributes:nil error:nil];
databaseURL = [applicationSupportURL URLByAppendingPathComponent:[dbName stringByAppendingString:#".sqlite"]];
}
[persistentCoordinator addPersistentStoreWithType:EncryptedStoreType configuration:nil URL:databaseURL
options:options error:error];
if (*error)
{
NSLog(#"Unable to add persistent store.");
NSLog(#"Error: %#\n%#\n%#", *error, [*error userInfo], [*error localizedDescription]);
}
return persistentCoordinator;
}
I call it in
- (void) initCoreDataProperties
{
NSError *error;
// Creating the Managed Object Model from momd
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:TBCoreDataModelFileName withExtension:#"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
// Creating the Encrypted Store Persistent Coordinator
_persistentStoreCoordinator = [EncryptedStore makeStoreWithOptions: [self persistentStoreOptions]
managedObjectModel: self.managedObjectModel
error: &error];
First, do not check the error for an error state. Only check the return of the call to -addPersistentStoreWithType.... The error can be populated even in a non-error condition.
Your code looks fine so I suspect if you turned off the encrypted store and used an Apple provided SQLite store then it would work fine. Which means the issue is with that third party code.
Since the third party code is not providing you with an error or a NSPersistentStore then it is failing poorly and you need to open a bug against the code base so that the author can address it.
Or you can walk through that third part code and see where it is failing and why.

Core Data populated in Simulator but not moving to Device

I've found lots of explanations and help here on stack but so far, no luck.
Pretty much, my myapp.sqlite (that I pre-populated) works fine on the simulator but when I run it on the iPad, it's empty.
So after trying different things, this is the closest I got :
I copy the sqlite db into the Bundle but I move it to the Library folder.
On my AppDelegate I do this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(#"Starting to save the DB to another location");
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString *targetPath = [libraryPath stringByAppendingPathComponent:#"myDB.sqlite"];
if (![[NSFileManager defaultManager] fileExistsAtPath:targetPath]) {
// database doesn't exist in your library path... copy it from the bundle
NSString *sourcePath = [[NSBundle mainBundle] pathForResource:#"myDB" ofType:#"sqlite"];
NSError *error = nil;
if (![[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:targetPath error:&error]) {
NSLog(#"Error: %#", error);
}
}
return YES;
}
then on the PersistentStoreCoordinator, I do this
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString *targetPath = [libraryPath stringByAppendingPathComponent:#"myDB.sqlite"];
// NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"naccApp.sqlite"];
// NSURL *storeURLLocal = [[NSBundle mainBundle] URLForResource:#"myDB" withExtension:#"sqlite"];
NSURL *storeURL = [NSURL URLWithString:targetPath];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
When I try to use the DB, (fetchRequest), I get an error :
CoreData SQL stores only support file URLs (got /var/mobile/Applications/2EB2AADD-DF9D-475F-A05E-BB138502471F/Library/myDB.sqlite).
The message is clear but I've tried almost all the help here and still nothing.
Needless to say, I'm new to Core Data, so please forgive the ignorance.
Oh, I'm using xCode 5.
Thx
NSURL *storeURL = [NSURL URLWithString:targetPath];
Should be:
NSURL *storeURL = [NSURL fileURLWithPath:targetPath];
so that you generate a file URL instead of a web URL.

Save the core data file inside the app's Library directory

In my Application i have stored The core data file is saved in the app's Document directory
like this
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"App.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;}
How can i store the core data file inside the app's Library directory.
-(NSString*)applicationLibraryDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
NSPersistentStoreCoordinator *persistentStoreCoordinator;
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSError *error=nil;
NSString *storePath = [[self applicationLibraryDirectory] stringByAppendingPathComponent: #"sample.sqlite"];
NSURL *storeUrl =[NSURL fileURLWithPath:storePath];
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error])
{
NSLog(#"store url %#",storeUrl);
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
exit(-1);
}
return persistentStoreCoordinator;
}
NSURL *libraryDirectory = [NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [[self libraryDirectory] URLByAppendingPathComponent:#"App.sqlite"];
// If the coordinator doesn't already exist, it is created and the application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
NSPersistentStoreCoordinator *persistentStoreCoordinator;
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSError *error=nil;
NSString *storePath = [[self applicationLibraryDirectory] stringByAppendingPathComponent: #"Arivanza.sqlite"];
NSURL *storeUrl =[NSURL fileURLWithPath:storePath];
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error])
{
NSLog(#"store url %#",storeUrl);
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
exit(-1);
}
return persistentStoreCoordinator;
}
This Complete method solved my problem thanks for the help.

Resources