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''
Related
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]
I want to create a entity in app A and save it into the app group shared space and access that entity in app B. This is my current approach, i'm not a master of core data so i'm sure i'm doing something wrong, the following code is for creating the entity in app A and saving it to the shared area. I receive no errors and the entity is created successfully
NSError * error = nil;
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"DataModel" withExtension:#"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc setPersistentStoreCoordinator:psc];
NSURL *storeURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:#"GROUP_IDENT"];
storeURL = [storeURL URLByAppendingPathComponent:#"sharedDB.sqlite"];
NSPersistentStore *store;
store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];
Report *report = [NSEntityDescription insertNewObjectForEntityForName:#"Report" inManagedObjectContext:moc];
report.categoryID = #"THIS IS A TEST";
if ([moc save:&error] == NO) {
NSAssert(NO, #"Error saving context: %#\n%#", [error localizedDescription], [error userInfo]);
}
And then trying to access this data in the other app as follows
NSError * error = nil;
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"DataModel" withExtension:#"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSAssert(mom != nil, #"Error initializing Managed Object Model");
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc setPersistentStoreCoordinator:psc];
NSURL *storeURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:#"GROUP_IDENT"];
storeURL = [storeURL URLByAppendingPathComponent:#"sharedDB.sqlite"];
NSError *error = nil;
NSPersistentStore *store = [psc persistentStoreForURL:storeURL];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Report"];
[request setEntity:[NSEntityDescription entityForName:#"Report" inManagedObjectContext:moc]];
[request setReturnsDistinctResults:YES];
NSArray * fetchedObjects = [moc executeFetchRequest:request error:&error];
store is always nil! If anyone has some suggestions or help that would be great!
You should use shared bundle:
NSBundle *sharedBundle = [NSBundle bundleWithIdentifier:#"com.company.sharedName"];
Instead of this:
[NSBundle mainBundle]
I can't wrap my head around the issue here: I save a PDF to disk - then load I try to load the PDF on a physical device and turn on airplane mode. File doesn't load. Can you help me ? It's clearly an issue of saving to and retrieving from the same directory.
SAVE LOCATION RETURNS:
Save location is : /var/mobile/Containers/Data/Application/A1F1B294-9282-483B-B2E1-76C586A9631E/Documents/fileurl.pdf
LOADING DIRECTORY RETURNS :
filePath is : /var/mobile/Containers/Data/Application/A1F1B294-9282-483B-B2E1-76C586A9631E/Documents/var/mobile/Containers/Data/Application/A1F1B294-9282-483B-B2E1-76C586A9631E/Documents/fileurl.pdf
SAVING THE PDF:
PDFViewController.m
- (IBAction)download:(id)sender {
NSManagedObjectContext *context = [self managedObjectContext];
NSError *error = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Downloads"];
[request setPredicate:[NSPredicate predicateWithFormat:#"pubnumber = %#", self.title]];
[request setFetchLimit:1];
NSUInteger count = [context countForFetchRequest:request error:&error];
if (count == NSNotFound) {
} else if (count == 0) {
NSData *pdfData = [[NSData alloc] initWithContentsOfURL:[
NSURL URLWithString:self.pdfURL]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* filePath = [documentsDirectory stringByAppendingPathComponent:self.pdfURL];
[pdfData writeToFile:filePath atomically:YES];
NSLog(#"Save location is : %#", filePath);
NSManagedObject *newDWNLD = [NSEntityDescription insertNewObjectForEntityForName:#"Downloads" inManagedObjectContext:context];
[newDWNLD setValue:self.title forKey:#"pubnumber"];
[newDWNLD setValue:titleString forKey:#"pubtitle"];
[newDWNLD setValue:filePath forKey:#"puburl"];
if (![context save:&error]) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Can't Save" message:#"Error handeling this request" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
alertView.tag = 2;
[alertView show];
}
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Stand Fast!" message:#"This document is already in your Downloads library" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
alertView.tag = 2;
[alertView show];
}
}
LOADING THE PDF:
DownloadsTableViewController.m
#import "PDFViewController.h"
#interface DownloadsTableViewController ()
#property (strong) NSMutableArray *downloads;
#property (weak) NSString *filePath;
#end
-(void)viewDidAppear:(BOOL)animated {
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"DWNLDView"];
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Downloads"];
self.downloads = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
self.filePath = [self.downloads valueForKey:#"puburl"];
[self.tableView reloadData];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"DWNLDView"];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
PDFViewController *pdfVC = [storyboard instantiateViewControllerWithIdentifier:#"PDFViewController"];
pdfVC.title = cell.textLabel.text;
pdfVC.DWNLDSpassedURL = self.filePath;
pdfVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
pdfVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:pdfVC animated:YES completion:nil];
}
PDFViewController.h
#import "MBProgressHUD.h"
#import <CoreData/CoreData.h>
#import <Parse/Parse.h>
#import <MessageUI/MessageUI.h>
<UIWebViewDelegate, UIAlertViewDelegate, MFMailComposeViewControllerDelegate>
#property (weak, nonatomic) NSString *DWNLDSpassedURL;
PDFViewController.m
- (void)viewDidLoad {
if ([[DWNLDed objectForKey:#"DWNLDView"] isEqual:#YES]) {
[self LocalQuery];
}
}
- (void)LocalQuery {
NSLog(#"Local Query initiated");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* filePath = [documentsDirectory stringByAppendingPathComponent:DWNLDSpassedURL];
NSLog(#"filePath is : %#", filePath);
NSURL *loadURL = [NSURL fileURLWithPath:filePath];
NSURLRequest *localDOC = [NSURLRequest requestWithURL:loadURL];
[self.webView loadRequest:localDOC];
}
Check your filePath in (void)LocalQuery I think it's not true
DownloadsTableViewController.m
tableView:didSelectRowAtIndexPath: set DWNLDSpassedURL = self.filePath
PDFViewController.m
NSString* filePath = [documentsDirectory stringByAppendingPathComponent:DWNLDSpassedURL]; can't get true document filePath
//documentsDirectory : /var/mobile/Containers/Data/Application/A1F1B294-9282-483B-B2E1-76C586A9631E/Documents/
//DWNLDSpassedURL: /var/mobile/Containers/Data/Application/A1F1B294-9282-483B-B2E1-76C586A9631E/Documents/fileurl.pdf
try this link
EDIT:
Solution:
PDFViewController.m
use NSString* filePath = DWNLDSpassedURL; instead NSString* filePath = [documentsDirectory stringByAppendingPathComponent:DWNLDSpassedURL];
OR
DownloadsTableViewController.m tableView:(UITableView *)tableView didSelectRowAtIndexPath:
pdfVC.DWNLDSpassedURL = yourFileName;
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
I'm trying to follow this tutorial:
http://www.raywenderlich.com/12170/core-data-tutorial-how-to-preloadimport-existing-data-updated
In this tutorial show how build a script for create a sqlite and import data from json.
I have write this:
static NSManagedObjectModel *managedObjectModel()
{
static NSManagedObjectModel *model = nil;
if (model != nil) {
return model;
}
NSString *path = #"AppChecker";
path = [path stringByDeletingPathExtension];
NSURL *modelURL = [NSURL fileURLWithPath:[path stringByAppendingPathExtension:#"mom"]];
model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return model;
}
static NSManagedObjectContext *managedObjectContext()
{
static NSManagedObjectContext *context = nil;
if (context != nil) {
return context;
}
#autoreleasepool {
context = [[NSManagedObjectContext alloc] init];
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel()];
[context setPersistentStoreCoordinator:coordinator];
NSString *STORE_TYPE = NSSQLiteStoreType;
NSString *path = [[NSProcessInfo processInfo] arguments][0];
path = [path stringByDeletingPathExtension];
NSURL *url = [NSURL fileURLWithPath:[path stringByAppendingPathExtension:#"sqlite"]];
NSError *error;
NSPersistentStore *newStore = [coordinator addPersistentStoreWithType:STORE_TYPE configuration:nil URL:url options:nil error:&error];
if (newStore == nil) {
NSLog(#"Store Configuration Failure %#", ([error localizedDescription] != nil) ? [error localizedDescription] : #"Unknown Error");
}
}
return context;
}
int main(int argc, const char * argv[])
{
#autoreleasepool {
// Create the managed object context
NSManagedObjectContext *context = managedObjectContext();
// Custom code here...
// Save the managed object context
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Error while saving %#", ([error localizedDescription] != nil) ? [error localizedDescription] : #"Unknown Error");
exit(1);
}
NSError* err = nil;
NSString* dataPath = [[NSBundle mainBundle] pathForResource:#"brands" ofType:#"json"];
NSArray* Brands = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath]
options:kNilOptions
error:&err];
NSLog(#"Imported Brands: %#", Brands);
NSString* dataPath2 = [[NSBundle mainBundle] pathForResource:#"products" ofType:#"json"];
NSArray* Products = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath2]
options:kNilOptions
error:&err];
NSLog(#"Imported Products: %#", Products);
}
return 0;
}
The problem is that, it create the .sqlite database(and structure is ok), but there isn't data!!!
My db is so:
And this is my json of brands for example:
[{
"id":"1",
"name":"TestBrand",
"description":"",
"website":"",
"email":"",
"address":"",
"phone":"",
"from_country_list":"CZ",
"created_at":"2013-11-24 11:51:17.363473",
"updated_at":"2013-11-24 11:51:17.363473"
}]
Any help/tips on why the data isn't imported in .sqlite db ?
Thanks a lot.
Continue with the tutorial. You will have to iterate through your objects created from the JSON files and add each instance to the Core Data object graph, populate it with the available attributes and finally save the context.
Only after this last step will the data be stored in the sqlite database.