Insert 50 objects in CoreData Table - ios

I want to insert 50 values in coredata ta
Question.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface Question : NSManagedObject
#property (nonatomic, retain) NSString * question;
#property (nonatomic, retain) NSString * answer;
#property (nonatomic, retain) NSString * mcqsa;
#property (nonatomic, retain) NSString * mcqsb;
#property (nonatomic, retain) NSString * mcqsc;
#property (nonatomic, retain) NSString * mcqsd;
Question.m
#import "Question.h"
#implementation Question
#dynamic question;
#dynamic answer;
#dynamic mcqsa;
#dynamic mcqsb;
#dynamic mcqsc;
#dynamic mcqsd;
#end
Insert Code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSManagedObjectContext *context = [self managedObjectContext];
Question *question = [NSEntityDescription
insertNewObjectForEntityForName:#"Question"
inManagedObjectContext:context];
question.question = #"What is capital of Australia?";
question.answer = #"Testville";
question.mcqsa = #"Sydney";
question.mcqsb = #"Canbera";
question.mcqsc = #"Berlin";
question.mcqsd = #"Bern";
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
.......
How can I insert multiple data, 50 questions with their mcqs (50 Question object)?
Is there any manual way using something else?

MagicalRecord a wrapper for CoreData provides some nice import features. You need to include the data that you need to import as plist/json in the bundle.
On the initial run you import data to coreData.
You can find a great tutorial on the same in the following link Importing data made easy
You need to create subclasses of NSManagedObject
on them you can call importFromObject: or importFromObject:. If you have full control over the structuring of the data this will happen out of the box without writing a single code for mapping data stored to core data entities.

You need a seed store, Pre-fill core data database then fetch it from device or simulator document directory and than add it to your bundle. At first run, you would copy database from bundle to Document directory and use that database onwards

You can use for loop to insert data.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
for(i=0; i<50; i++) {
NSManagedObjectContext *context = [self managedObjectContext];
Question *question = [NSEntityDescription
insertNewObjectForEntityForName:#"Question"
inManagedObjectContext:context];
question.question = #"What is capital of Australia?";
question.answer = #"Testville";
question.mcqsa = #"Sydney";
question.mcqsb = #"Canbera";
question.mcqsc = #"Berlin";
question.mcqsd = #"Bern";
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
.......
}

Here is the code:
NSString* plistPath = [[NSBundle mainBundle] pathForResource:#"QuesList" ofType:#"plist"];
NSArray *quesList = [[NSArray alloc]initWithContentsOfFile:plistPath];
for(NSDictionary *object in quesList){
NSString *str1 = [object objectForKey:#"question"];
NSString *str2 = [object objectForKey:#"answer"];
NSString *str3 = [object objectForKey:#"mcqsa"];
NSString *str4 = [object objectForKey:#"mcqsb"];
NSString *str5 = [object objectForKey:#"mcqsc"];
Question *question = [NSEntityDescription
insertNewObjectForEntityForName:#"Question"
inManagedObjectContext:context];
question.question = str1;
question.answer =str2;
question.mcqsa =str3;
question.mcqsb =str4;
question.mcqsc = str5;
}
And
Also make sure that you run this code only once, otherwise it woudld create duplicate objects

Related

IOS: NSKnownKeysDictionary1 error

I have an object selectedActivity defined as follows:
#property (strong, nonatomic) Activities *selectedActivity;
At the point I need to work with it logs out as:
{
actname = "Running";
aid = 23;
}
The Activities object is an NSManaged object and its .h file looks like this.
#interface Activities : NSManagedObject
#property (nonatomic, retain) NSString * actname;
#property (nonatomic, retain) NSNumber * aid;
#end
I am trying to place one of the object properties in a variable to work with it using the following:
NSNumber *aid = _selectedActivity.aid;
However, the above line gives the following error message:
[NSKnownKeysDictionary1 aid]: unrecognized selector sent to instance 0x147842fb0
Can anyone explain this error and how to fix it?
Thanks for any suggestions.
Update:
setting of selected activity
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
_selectedActivity =([_activities objectAtIndex:row]);
NSLog(#"selectedActivity in pickerview%#",_selectedActivity);
}
//activities in .h file
#property (strong, nonatomic) NSArray *activities;
//setting of activities
self.activities= [self getActivities];
//method that gets activities
- (id) getActivities{
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Activities"];
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"created" ascending:NO];
[fetchRequest setSortDescriptors:#[sort]];
NSError *error = nil;
self.managedObjectContext = [Model sharedInstance].managedObjectContext;
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest
error:&error];
NSMutableArray *mutableresults = [results mutableCopy];
[mutableresults removeObjectIdenticalTo:[NSNull null]];
return mutableresults;
}
The results are coming as a dictionary.
instead of the usual NSManagedObject-style value retrieval:
Objective-C
NSString *actname = _selectedActivity.actname;
NSNumber *aid = _selectedActivity.aid;
Swift
let actname:String = _selectedActivity.actname
let aid:Int = _selectedActivity.aid
Use the NSDictionary-style value retrieval, like so:
Objective-C:
NSString *actname = [_selectedActivity valueForKey:#"actname"];
NSNumber *aid = [[_selectedActivity valueForKey:#"aid"] intValue];
Swift (tested as of 3.0.1)
_selectedActivity(forKey: "actname") as! String
_selectedActivity.value(forKey: "aid") as! Int

iOS, Core Data is adding new object to wrong entity every time when i save context?

i new to core data. here i am trying to save bunch of Statement in one Month.But i dont know how to insert object in core data with relationship. what my code is doing, it saving month in Month entity and statements in Statement entity without any relationship. every time i save it create new object in Month entity. my DataModel has One to Many Relationships. for example current (month) November than i want to insert few statement related to November. than next month December i want to insert few statement related to December. thats what i am trying to achieve. sorry for bad my english.
`
NSManagedObjectContext *context = [self managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Month" inManagedObjectContext:context];
Month *month = [[Month alloc] initWithEntity:entity insertIntoManagedObjectContext:context];
Statement *statement = [NSEntityDescription insertNewObjectForEntityForName:#"Statement" inManagedObjectContext:context];
statement.title = self.enterTextGreenViewTextField.text;
NSNumber *aNum = [NSNumber numberWithDouble:savingAmount];
statement.amount =aNum;
statement.isIncome = [NSNumber numberWithBool:isIncome];
[month addStatementsObject:statement];
NSError *error;
if (![context save:&error]) {
FATAL_CORE_DATA_ERROR(error);
return;
}
NSLog(#"savingStatement ****");
`
#import "Month.h"
NS_ASSUME_NONNULL_BEGIN
#interface Month (CoreDataProperties)
#property (nullable, nonatomic, retain) NSDate *monthOfStatement;
#property (nullable, nonatomic, retain) NSSet<Statement *> *statements;
#end
#interface Month (CoreDataGeneratedAccessors)
- (void)addStatementsObject:(Statement *)value;
- (void)removeStatementsObject:(Statement *)value;
- (void)addStatements:(NSSet<Statement *> *)values;
- (void)removeStatements:(NSSet<Statement *> *)values;
#end
NS_ASSUME_NONNULL_END
And
#import "Statement.h"
NS_ASSUME_NONNULL_BEGIN
#interface Statement (CoreDataProperties)
#property (nullable, nonatomic, retain) NSNumber *amount;
#property (nullable, nonatomic, retain) NSNumber *isIncome;
#property (nullable, nonatomic, retain) NSString *title;
#property (nullable, nonatomic, retain) Month *month;
#end
NS_ASSUME_NONNULL_END
Almost right, you have to create the two entities and then bind their relationship:
NSEntityDescription *month = [NSEntityDescription insertNewObjectForEntityForName:#"Month" inManagedObjectContext:[self managedObjectContext]];
Statement *statement = [NSEntityDescription insertNewObjectForEntityForName:#"Statement" inManagedObjectContext:context];
statement.title = self.enterTextGreenViewTextField.text;
NSNumber *aNum = [NSNumber numberWithDouble:savingAmount];
statement.amount =aNum;
statement.isIncome = [NSNumber numberWithBool:isIncome];
statement.month=month;
This line i don't know if manually generating the set is necessary, but I do it nonetheless:
NSMutableSet *monthStatements;
if(month.statements){
monthStatements=[NSMutableSet setWithSet:month.statements];
}else{
monthStatements=[NSMutableSet alloc] init];
}
[monthStatements addObject:statement];
month.statements = monthStatements;
Finally saving:
NSError *error=nil;
if (![context save:&error]) {
FATAL_CORE_DATA_ERROR(error);
return;
}
In my opinion this should work as charm (haven't tried it though) :-)
** Edit:
Fetching:
NSArray *fetchedObjects;
NSError *error=nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Store" inManagedObjectContext:[self managedObjectContext]];
[fetchRequest setEntity: entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"code==%#", code];
[fetchRequest setPredicate:predicate];
fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
You typically will try to fetch the month in case it already exists, and if it doesn't you create it with the code I gave you. I don't know what you mean by creating new relationships though....

Core data - to implement OneToMany relationship with cascade delete rule

Need help in implementing delete rule in a core data relationship , I gone through all the article on the net but can't understand to implement the delete rule , does creating relationship takes cares of deletion process (which I doubt ) , I have creates the below entity with rule , but on deleting a entry in List_Main does not delete the entry in list_Item , I guess linking in not done (don't know how to do that )
I have two entity
Entity --------Relation Ship ---- Destination ---- Inverse ---- Properties ---- Delete Rule
List_main -- Main_to_Item ---- List_Item ----- Item_to_Main -- Optional -- Cascade
List_Item -- Item_to_Main ----- list_Main ------ Main_to_Item --- optional --- nullify
List_Main.h
#property (nonatomic, retain) NSString * list_Name;
#property (nonatomic, retain) NSDate * list_Reminder_Date;
#property (nonatomic, retain) NSNumber * list_Reminder_Flag;
#property (nonatomic, retain) NSSet *main_to_item;
#end
#interface List_Main (CoreDataGeneratedAccessors)
- (void)addMain_to_itemObject:(List_Item *)value;
- (void)removeMain_to_itemObject:(List_Item *)value;
- (void)addMain_to_item:(NSSet *)values;
- (void)removeMain_to_item:(NSSet *)values;
#end
List_Item.h
#interface List_Item : NSManagedObject
#property (nonatomic, retain) NSString * list_Items;
#property (nonatomic, retain) NSString * list_Name;
#property (nonatomic, retain) List_Main *item_to_main;
Now when in first view user enters the List Name in List_main
FirstView.m
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *newItem = [NSEntityDescription insertNewObjectForEntityForName:#"List_Main" inManagedObjectContext:context];
[newItem setValue:self.listName.text forKey:#"list_Name"];
NSDate *currentDate = [NSDate date];
currentDate = [self dateWithOutTime:currentDate];
[newItem setValue:currentDate forKey:#"list_Reminder_Date"];
[newItem setValue:NO forKey:#"list_Reminder_Flag"];
// Save
NSError *error = nil;
if (![context save:&error]) {
NSAssert(NO, #"Save should not fail");
[self showAlert];
}
After that the control goes to secondView to enter Item and makes entires in List_Item
secondView.m
NSManagedObject *category1 = [NSEntityDescription insertNewObjectForEntityForName:#"List_Item" inManagedObjectContext:self.context];
[category1 setValue:self.listName forKey:#"list_Name"];
[category1 setValue:combinedThumbNail forKey:#"list_Items"];
NSError *error = nil;
if (![self.context save:&error]) {
NSAssert(NO, #"Save should not fail");
[self showAlert];
}
and I have a delete command for respective entity
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
[context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
Now how should I implement the delete rule using the relationship , really a showstopper for me :((
If you can point out any good tutorial that will also do

EXC_BAC_ACCESS error when saving core data Boolean field

I am getting a EXC_BAC_ACCESS error when attempting to save a TRUE value into a managed object that contains a Boolean attribute.
id delegate = [[UIApplication sharedApplication] delegate];
self.managedObjectContext = [delegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"TrafficCameraInfo"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"code=%#",self.selectedTrafficCamera.code]];
NSError *error;
TrafficCameraInfo *cgTrafficCamera;
cgTrafficCamera = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] lastObject];
NSString *alertMessage;
if (cgTrafficCamera.favourite == NO){
cgTrafficCamera.name = #"TEST"; <-- works ok
cgTrafficCamera.favourite = 1; <-- causes an error
} else {
cgTrafficCamera.favourite = 0;
}
error = nil;
if (![self.managedObjectContext save:&error]) {
The managed object interface looks like this:
#interface TrafficCameraInfo : NSManagedObject
#property (nonatomic, retain) NSString *code;
#property (nonatomic, retain) NSString *postCode;
#property (nonatomic, retain) NSNumber *latitude;
#property (nonatomic, retain) NSNumber *longitude;
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *url;
#property (nonatomic) Boolean favourite;
#end
Elsewhere in my app i am updating another Boolean field by passing a 1 to it and am not encountering a problem.
Any ideas what is causing the error?
I think in your core data attribute table you define "favorite" variable to BOOL,well that means it's an NSNumber Type,so you should set the data using NSNumber
A Boolean is a simple, scalar, non-pointer datatype. Core Data properties are always stored as objects. The Objective-C object wrapper for numeric datatypes is NSNumber. So if favourite is a regular stored property, you should declare it as:
#property (nonatomic, retain) NSNumber *favourite;
Assignment would be done like this:
cgTrafficCamera.favourite = [NSNumber numberWithBool:YES]; // Obj-C style is "YES/NO" for BOOL
Or this if you prefer:
cgTrafficCamera.favourite = [NSNumber numberWithBool:1];
If you don't need to store the Boolean, you can leave it as such and make it a transient property. You'll probably need to get rid of the "(nonatomic)" in that case.

Core Data one-to-many relation won't take values, how do I have do use the accessor methods?

I want to save a method, which has some relations to other Entities. The approach and background are to-one relations, but the method should have be able to have several tipps and examples. I already looked at many other questions and tutorials but I do not know why it won't work.
dataToBeSaved is a Dictionary containing the data as Strings I want to assign to the method.
Here is Method.h
#interface Method : NSManagedObject
#property (nonatomic, retain) NSNumber * id;
#property (nonatomic, retain) NSString * name;
#property (nonatomic, retain) Approach *methodtoapproach;
#property (nonatomic, retain) Background *methodtobackground;
#property (nonatomic, retain) NSSet *methodtoexample;
#property (nonatomic, retain) NSSet *methodtotipps;
#end
#interface Method (CoreDataGeneratedAccessors)
- (void)addMethodtoexampleObject:(Example *)value;
- (void)removeMethodtoexampleObject:(Example *)value;
- (void)addMethodtoexample:(NSSet *)values;
- (void)removeMethodtoexample:(NSSet *)values;
- (void)addMethodtotippsObject:(Tipps *)value;
- (void)removeMethodtotippsObject:(Tipps *)value;
- (void)addMethodtotipps:(NSSet *)values;
- (void)removeMethodtotipps:(NSSet *)values;
#end
and here is my code, I let the commented sections in it, so you can see what I tried to to...
Method *newMethod = [NSEntityDescription insertNewObjectForEntityForName:#"Method" inManagedObjectContext:managedObjectContext];
// [newMethod setValue:[dataToBeSaved objectForKey:#"name"] forKey:#"name"];
// [newMethod setValue:[NSNumber numberWithInt:11] forKey:#"id"];
newMethod.name = [dataToBeSaved objectForKey:#"name"];
newMethod.id = [NSNumber numberWithInt:11];
newMethod.methodtoapproach.summary = [dataToBeSaved objectForKey:#"summary"];
newMethod.methodtobackground.background = [dataToBeSaved objectForKey:#"background"];
NSMutableSet *tippsSet = [[NSMutableSet alloc] initWithObjects:[dataToBeSaved objectForKey:#"tipps"], nil];
NSMutableSet *exampleSet = [[NSMutableSet alloc] initWithObjects:[dataToBeSaved objectForKey:#"example"], nil];
[newMethod addMethodtotipps:tippsSet];
[newMethod addMethodtoexample:exampleSet];
// [[newMethod mutableSetValueForKey:#"methodtotipps"] addObject:[dataToBeSaved objectForKey:#"tipps"]];
// [[newMethod mutableSetValueForKey:#"methodtoexample"] addObject:[dataToBeSaved objectForKey:#"example"]];
// [newMethod addMethodtotippsObject:[dataToBeSaved objectForKey:#"tipps"]];
// [newMethod addMethodtoexampleObject:[dataToBeSaved objectForKey:#"example"]];
// newMethod.methodtotipps.tipps = [dataToBeSaved objectForKey:#"tipps"];
// newMethod.methodtoexample.example = [dataToBeSaved objectForKey:#"example"];
if I run the app exactly like that, I get the error:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString entity]: unrecognized selector sent to instance xxx
if you need more information, just post it in the comments...
Actually, it now worked for me like this:#
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
managedObjectContext = [appDelegate managedObjectContext];
fetchedResultsController = [appDelegate fetchedResultsController];
Method *newMethod = [NSEntityDescription insertNewObjectForEntityForName:#"Method" inManagedObjectContext:managedObjectContext];
Approach *newApproach = [NSEntityDescription insertNewObjectForEntityForName:#"Approach" inManagedObjectContext:managedObjectContext];
Background *newBackground = [NSEntityDescription insertNewObjectForEntityForName:#"Background" inManagedObjectContext:managedObjectContext];
Tipps *newtipp = [NSEntityDescription insertNewObjectForEntityForName:#"Tipps" inManagedObjectContext:managedObjectContext];
Example *newExample = [NSEntityDescription insertNewObjectForEntityForName:#"Example" inManagedObjectContext:managedObjectContext];
[newMethod setName:[dataToBeSaved objectForKey:#"name"]];
[newMethod setId:[NSNumber numberWithInt:11]];
newApproach.summary = [dataToBeSaved objectForKey:#"summary"];
newBackground.background = [dataToBeSaved objectForKey:#"background"];
newtipp.tipps = [dataToBeSaved objectForKey:#"tipps"];
newExample.example = [dataToBeSaved objectForKey:#"example"];
NSMutableSet *tippsSet = [NSMutableSet set];
NSMutableSet *examplesSet = [NSMutableSet set];
[newMethod setMethodtoapproach:newApproach];
[newMethod setMethodtobackground:newBackground];
[newMethod setMethodtoexample:examplesSet];
[newMethod setMethodtotipps:tippsSet];
[newMethod addMethodtoexampleObject:newExample];
[newMethod addMethodtotippsObject:newtipp];
NSError *error;
if (managedObjectContext != nil)
{
if([managedObjectContext hasChanges])
{
[managedObjectContext save:&error];
if(error)
{
NSLog(#"Error Saving data: %#", [error userInfo]);
}
}
}
might be just what #Fogmeister meant but I'm (up till now) fine with how it works. Maybe later there is some optimization necessary... I'll post it here if so...
Yeah, I was caught out by this also.
If you want to use the methods...
- (void)add<blah>Object...
Then you need to write it yourself.
What I actually do is create the relationship the other way around.
instead of creating the child and then adding the child to the parent. I create the child and then tell the child what its parent is.

Resources