I am getting error in the search part. when i enter the song name i should get the lyrics there but getting an error says 'executeFetchRequest:error: A fetch request must have an entity.' i used the following code
-(void)findLyrics
{
LyricsAppDelegate *appDelegate = [[UIApplication sharedApplication]
delegate];
NSManagedObjectContext *managedObjectContext = [appDelegate managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription
entityForName:#"Lyrics"inManagedObjectContext:managedObjectContext];
NSManagedObject *LyricsObjectEnglish;
LyricsObjectEnglish = [NSEntityDescription insertNewObjectForEntityForName:#"English_Songs"
inManagedObjectContext:managedObjectContext];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(MovieSongName = %#)",song_name.text];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error];
if ([objects count] == 0)
{
//status.text = #"No matches";
} else {
matches = [objects objectAtIndex:0];
song_lyrics.text = [matches valueForKey:#"SongLyrics"];
song_name.text = [matches valueForKey:#"MovieSongName"];
// status.text = [NSString stringWithFormat:#"%d matches found", [objects count]];
}
[request release];
}
Any body please help..
Related
My coredata methods are here. How to write unit test case to check this.
Method to save to coredata
- (void)saveUserDetails:(Model *)userDetail {
if(userDetail != nil) {
UserEntity *user = [NSEntityDescription insertNewObjectForEntityForName:#“EntityName” inManagedObjectContext:[self sharedContext]];
NSArray *fetchArray = [self fetchUserWithUsername:userDetail.username];
if ([fetchArray count] == 0) {
user.username = userDetail.username;
[self saveContext];
}
}
}
Method to fetch from coredata
- (NSArray *)fetchUserWithUsername:(NSString *)username {
if (username != nil) {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *userEntity = [NSEntityDescription entityForName:#“EntityName” inManagedObjectContext:[self sharedContext]];
[fetchRequest setEntity:userEntity];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"username = %#", username];
NSError *error;
NSArray *fetchedObjects = [[self sharedContext] executeFetchRequest:fetchRequest error:&error];
return fetchedObjects;
}
return nil;
}
Create an in-memory store and inject this into your object.
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"MyResource" withExtension:#"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
XCTAssertTrue([psc addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:NULL] ? YES : NO, #"Should be able to add in-memory store");
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
context.persistentStoreCoordinator = psc;
I am using core data for my application.It works fine on simulator but not retreiving the details on real device.Device is of iOS6.1.This is the code i am using:
- (NSManagedObjectContext *) getCurrentMangedContext
{
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"ForceData" withExtension:#"momd"];
NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSURL *storeURL = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]URLByAppendingPathComponent:#"ForceData.sqlite"];
NSError *error = nil;
NSPersistentStoreCoordinator *persistantStroreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel];
if (![persistantStroreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
{
}
NSManagedObjectContext *managedContext = [[NSManagedObjectContext alloc] init] ;
[managedContext setPersistentStoreCoordinator:persistantStroreCoordinator];
modelURL = nil;
return managedContext;
}
This is how i am saving my login details and it is not giving any error.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"User" inManagedObjectContext:context];
[request setEntity:entity];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
if (emailString != nil)
{
[newManagedObject setValue:emailString forKey:#"email"];
}
if (genderString != nil)
{
[newManagedObject setValue:genderString forKey:#"gender"];
}
if (fNameString != nil)
{
[newManagedObject setValue:fNameString forKey:#"firstName"];
}
if (lNameString != nil)
{
[newManagedObject setValue:lNameString forKey:#"lastName"];
}
if (userIDString != nil)
{
[newManagedObject setValue:userIDString forKey:#"userID"];
}
NSError *error = nil;
if (![context save:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
// Insert User details to the user DB <--------------------------
And this is how i am retrieving:
- (User *) getActiveUser
{
NSManagedObjectContext *context = [self getCurrentMangedContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"User" inManagedObjectContext:context];
[request setEntity:entity];
NSError *errorFetch = nil;
NSArray *array = [context executeFetchRequest:request error:&errorFetch];
User *objUser = (User *) [array lastObject];
NSLog(#"%#",objUser);
return objUser;
}
But i am not getting the user details on device but getting on simulator.anyone faced this same?
In your case I'd suggest that ARC releases your managedObjectContext after executing the fetch request.
Make sure that you hold a strong reference to the appropriate managedObjectContext during the whole lifetime of your managedObject somewhere in your app (e.g. your ApplicationDelegate). A NSManagedObject can't live without it's managedObjectContext. The Core Data project template shows how to do that.
Further information about ARC and strong references: https://developer.apple.com/library/mac/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html
I have a method for adding stamp to the card, from QR code reader to web service
my question is,
Here is my code:
- (void)addStamp
{
NSString *url = [_URL stringByAppendingString:#"add-stamp"];
NSString *post = [NSString stringWithFormat:#"userId=%#&code=%#", self.userId, self.code ];
post = [post stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *postData = [NSData dataWithBytes:[post UTF8String]
length:[post lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL
URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:600];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
}
Rightnow I want to update my DB with new method -> if the code is repeated add stamp, if not create add a new card:
-(void)addStampInDB:(int)cardId
{
NSManagedObjectContext* managedObjectContext = [(AppDelegate*) [[UIApplication
sharedApplication] delegate] managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Card"
inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"remote_id = %d", cardId];
[fetchRequest setPredicate:predicate];
[managedObjectContext lock];
NSError *error;
NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest
error:&error];
[managedObjectContext unlock];
Card *d = nil;
if([fetchedObjects count] > 0 ){
d = [fetchedObjects objectAtIndex:0];
cardId++;
} else{
d = [NSEntityDescription insertNewObjectForEntityForName:#"Card"
inManagedObjectContext:managedObjectContext];
}
NSArray *test;
for(NSDictionary *stamp in test)
{
d.remote_id = [NSNumber numberWithInt:[[stamp objectForKey:#"id"] intValue]];
d.stampNumber = [NSNumber numberWithInt:[[stamp objectForKey:#"stampNumber"] intValue]];
d.createdAt = [NSDate dateWithTimeIntervalSince1970:[[stamp objectForKey:#"createdAt"]
intValue]];
[managedObjectContext lock];
NSError *error;
if (![managedObjectContext save:&error])
{
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
NSLog(#"Failed to save to data store: %#", [error localizedDescription]);
NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if(detailedErrors != nil && [detailedErrors count] > 0) {
for(NSError* detailedError in detailedErrors) {
NSLog(#" DetailedError: %#", [detailedError userInfo]);
}
} else {
NSLog(#" %#", [error userInfo]);
}
}
[managedObjectContext unlock];
}
}
I don't know if I'm in a right way or not and also how I can test my method?
I'm not very sure about your question but I'll try to give some hints.
First
Card *d = nil;
if([fetchedObjects count] > 0 ){
d = [fetchedObjects objectAtIndex:0];
cardId++;
} else{
d = [NSEntityDescription insertNewObjectForEntityForName:#"Card"
inManagedObjectContext:managedObjectContext];
}
Here you have found an existing card, you use it, else you create a new. Question: what about cardId? Where is it used?
Second
for(NSDictionary *stamp in test)
{
d.remote_id = [NSNumber numberWithInt:[[stamp objectForKey:#"id"] intValue]];
d.stampNumber = [NSNumber numberWithInt:[[stamp objectForKey:#"stampNumber"] intValue]];
d.createdAt = [NSDate dateWithTimeIntervalSince1970:[[stamp objectForKey:#"createdAt"]
intValue]];
// other code here
}
If you loop test, you overwrite the value of your card d each time. Is it right?
Third
for(NSDictionary *stamp in test)
{
// other code here
}
// save here
Move the save out of the for loop. This boost performances in your app. It is not necessary to save each time in your loop. Do it at the end only.
Hope that helps.
P.S. If you want to know something else let me know.
i need help!!!^^
I write in my attributes (name,prename) the two names of the person and save them. If i try to access the attrubutes in another view then they are nil. I don't understand why?!?
I did it this way. I get the profileContext with the method getProfile and i access the Attributes with the Dot-Notation, then i save it. My NSLog show me the right name and my fetch too.
ownProfile = [[MyProfile alloc] init];
profileContext = [ownProfile getProfile];
ownProfile = (MyProfile*)[NSEntityDescription insertNewObjectForEntityForName:#"MyProfile" inManagedObjectContext:profileContext];
ownProfile.Vorname = #"Max";
ownProfile.Nachname = #"Wilson";
NSLog(#"%#",ownProfile.Nachname);
if ([profileContext hasChanges]) {
NSLog(#"It has changes!");
[profileContext save:nil];
}
//Fetching
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"MyProfile" inManagedObjectContext:profileContext];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
NSArray *array = [profileContext executeFetchRequest:request error:nil];
for (int i=0; i < [array count]; i++) {
MyProfile *object = [array objectAtIndex:i];
NSLog(#"Name: %#",object.Nachname);
}
if i try to access the attributes in another ViewController subclass they are nil. This is the code:
- (void)viewDidLoad {
[super viewDidLoad];
ownProfile = [[MyProfile alloc] init];
NSManagedObjectContext *profileContext = [ownProfile getProfile];
ownProfile = [NSEntityDescription insertNewObjectForEntityForName:#"MyProfile" inManagedObjectContext:profileContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"MyProfile" inManagedObjectContext:profileContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
[request setIncludesPropertyValues:NO]; //only fetch the managedObjectID
NSArray *array = [profileContext executeFetchRequest:request error:nil];
[request release];
MyProfile *object = [array objectAtIndex:[array count]-1];
NSLog(#"%#",object);
}
my getProfile method is in the NSManagedObjectClass and look like this:
-(NSManagedObjectContext*) getProfile {
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],
NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES],
NSInferMappingModelAutomaticallyOption, nil];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSLog(#"basePath = %#",basePath);
NSURL *storeUrl = [NSURL fileURLWithPath:[basePath stringByAppendingFormat:#"CoreData.sqlite"]];
NSPersistentStoreCoordinator *persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:nil]];
NSLog(#"PersistentStore = %#",persistentStoreCoordinator);
NSError *error = nil;
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
NSLog(#"error loading persistent store..");
[[NSFileManager defaultManager] removeItemAtPath:storeUrl.path error:nil];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
NSManagedObjectContext *profile = [[NSManagedObjectContext alloc] init];
[profile setPersistentStoreCoordinator:persistentStoreCoordinator];
return profile;
}
Please help me!!!^^
Hey guys...I solved my problem!!! :)
My fault was that I add in the viewDidLoad-Method in the line
ownProfile = [NSEntityDescription insertNewObjectForEntityForName:#"MyProfile" inManagedObjectContext:profileContext];
another object in the persistentStore and i was always reading the new object where the attributes are nil...of course^^
I have three Classes for which I am extending NSManagedObject (I know this isn't required but I wanted the property notation). Theses Classes are QuestionSet, Question and Answer. My data model is setup so that there's a many to many between them like so: QuestionSet <<->> Question <<->> Answer. I load up everything from a server and it save successfully meaning I look in the .db file and it's all how I expect, if I immediately NSLog the array questionsets they look great and if I go take a quiz it works great.
However if I NSLog that array anywhere but right after where I load them from the server, it crashes my app. The quiz still runs fine so I know the data is in there and in the expected format. Does this have something to do with Core Data clearing out space and then my relationships don't 'lazy loaded' when I'm just trying to log them? Sorry, still wrapping my head around core data.
This bit works, I load from the server and at the bottom I 'loadTrivia' and log what I get. The issue comes if at sometime later during the course of the app execution, an NSLog of the questionsets will fail.
- (void)loadQuestionSetFromNetworkWithID:(NSNumber *)p_id andTitle:(NSString *)p_title
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:kTriviaQuestionSetURL, [p_id intValue]]]];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSArray *questions = [[[sbjson objectWithString:json_string error:nil] valueForKeyPath:#"Q"] objectAtIndex:0];
NSError *error;
NSFetchRequest *questionsetRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *questionsetEntity = [NSEntityDescription entityForName:#"QuestionSet" inManagedObjectContext:[self managedObjectContext]];
NSPredicate *questionsetPredicate = [NSPredicate predicateWithFormat:#"id = %d", [p_id intValue]];
[questionsetRequest setEntity:questionsetEntity];
[questionsetRequest setPredicate:questionsetPredicate];
QuestionSet *qs = nil;
NSArray *questionSetObjects = [[self managedObjectContext] executeFetchRequest:questionsetRequest error:&error];
if (questionSetObjects == nil){
// Handle errors
}
if ([questionSetObjects count] > 0)
qs = [questionSetObjects objectAtIndex:0];
else
qs = [NSEntityDescription insertNewObjectForEntityForName:#"QuestionSet" inManagedObjectContext:[self managedObjectContext]];
qs.id = p_id;
qs.title = p_title;
for (int i = 0; i < [questions count]; i++)
{
NSFetchRequest *questionRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *questionEntity = [NSEntityDescription entityForName:#"Question" inManagedObjectContext:[self managedObjectContext]];
NSPredicate *questionPredicate = [NSPredicate predicateWithFormat:#"(id = %d)", [[[questions objectAtIndex:i] objectForKey:#"id"] intValue]];
[questionRequest setEntity:questionEntity];
[questionRequest setPredicate:questionPredicate];
Question *q = nil;
NSArray *questionObjects = [[self managedObjectContext] executeFetchRequest:questionRequest error:&error];
if (questionObjects == nil){
// Handle errors
}
if ([questionObjects count] > 0)
q = [questionObjects objectAtIndex:0];
else
q = [NSEntityDescription insertNewObjectForEntityForName:#"Question" inManagedObjectContext:[self managedObjectContext]];
q.id = [NSNumber numberWithInt:[[[questions objectAtIndex:i] objectForKey:#"id"] intValue]];
q.question = [[questions objectAtIndex:i] objectForKey:#"text"];
q.answer = [NSNumber numberWithInt:[[[questions objectAtIndex:i] objectForKey:#"ca"] intValue]];
for (int j = 0; j < [[[questions objectAtIndex:i] objectForKey:#"A"] count]; j++)
{
NSFetchRequest *answerRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *answerEntity = [NSEntityDescription entityForName:#"Answer" inManagedObjectContext:[self managedObjectContext]];
NSPredicate *answerPredicate = [NSPredicate predicateWithFormat:#"(id = %d)", [[[[[questions objectAtIndex:i] objectForKey:#"A"] objectAtIndex:j] objectForKey:#"id"] intValue]];
[answerRequest setEntity:answerEntity];
[answerRequest setPredicate:answerPredicate];
Answer *a = nil;
NSArray *answerObjects = [[self managedObjectContext] executeFetchRequest:answerRequest error:&error];
if (answerObjects == nil){
// Handle errors
}
if ([answerObjects count] > 0)
a = [answerObjects objectAtIndex:0];
else
a = [NSEntityDescription insertNewObjectForEntityForName:#"Answer" inManagedObjectContext:[self managedObjectContext]];
a.id = [NSNumber numberWithInt:[[[[[questions objectAtIndex:i] objectForKey:#"A"] objectAtIndex:j] objectForKey:#"id"] intValue]];
a.answer = [[[[questions objectAtIndex:i] objectForKey:#"A"] objectAtIndex:j] objectForKey:#"text"];
a.questions = [a.questions setByAddingObject:q];
q.answers = [q.answers setByAddingObject:a];
[answerRequest release];
}
q.questionsets = [q.questionsets setByAddingObject:qs];
qs.questions = [qs.questions setByAddingObject:q];
[questionRequest release];
}
[questionsetRequest release];
[[self managedObjectContext] save:&error];
[json_string release];
[self loadTrivia];
NSLog(#"After Load: %#", self.questionsets);
}
This function fetches all the QuestionSet objects from the db and stores the array in an ivar.
- (BOOL)loadTrivia
{
NSError *error;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"QuestionSet" inManagedObjectContext:[self managedObjectContext]];
[request setEntity:entity];
self.questionsets = [[self managedObjectContext] executeFetchRequest:request error:&error];
return YES;
}
Just for completeness, here are my description methods in my classes
from QuestionSet.h
- (NSString *)description
{
return [NSString stringWithFormat:#"\
\n\tid: %#\
\n\ttitle: %#\
\n\tquestions: %#\n",
self.id,
self.title,
self.questions];
}
from Question.h
- (NSString *)description
{
return [NSString stringWithFormat:#"\
\n\tid: %#\
\n\tanswer: %#\
\n\tquestion: %#\
\n\tanswers: %#\n",
self.id,
self.answer,
self.question,
self.answers];
}
from Answer.h
- (NSString *)description
{
return [NSString stringWithFormat:#"\
\n\tid: %#\
\n\tanswer: %#\n",
self.id,
self.answer];
}
You shouldn't subclass the description method (Link):
Although the description method does not cause a fault to fire, if you implement a custom description method that accesses the object’s persistent properties, this will cause a fault to fire. You are strongly discouraged from overriding description in this way.
I tested your loadTrivia code (with a different entityName) on my app and it worked fine.
Did you have a look at the NSError (you should initialize it with =nil):
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
Also you should release the NSFetchRequest after execution in - (BOOL)loadTrivia.