I have some object that is image that is in relation with object user mani-to-one like that Image <<---> User. Now that i want to do, when the user is login i display a button to each images for add to favourites, when i click this button is run this code:
User * user = [[UserController sharedInstance] currentUser];
Image * image = (Image*)[user.managedObjectContext objectWithID:[self.yacht objectID]];
yacht.whoLiked = user
the problem is not i the same controller but in the Main Controller before, because what i do is load al the image's thumb in a collection view (and in this controller load all the data from the DB) then when i press the thumb i go in another controller that show me the big image and the button for add favourites, when i press it and then come back to the old controller in the viewDidAppear of the old controller i reload every time the data from the db but i can't see any change, if i change section (controller) and i come back to see i see the data update
this is how I call the Db from Main Controller:
- (void)fetchImages
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Image"];
request.predicate = [NSPredicate predicateWithFormat:#"ANY whichCategories.name =[cd] %#", self.category.name];
NSSortDescriptor *sortName = [[NSSortDescriptor alloc] initWithKey:#"headline" ascending:YES selector:#selector(localizedCaseInsensitiveCompare:)];
request.sortDescriptors = [NSArray arrayWithObject:sortName];
NSError * error = nil;
self.images = [self.database.managedObjectContext executeFetchRequest:request error:&error];
[self.collectionView reloadData];
}
- (void)useDocument
{
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.database.fileURL path]]) {
// CREATE
[self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self fetchImages];
}];
} else if (self.database.documentState == UIDocumentStateClosed) {
// OPEN
[self.database openWithCompletionHandler:^(BOOL success) {
[self fetchImages];
}];
} else if (self.database.documentState == UIDocumentStateNormal) {
// USE
[self fetchImages];
}
}
- (void)setDatabase:(UIManagedDocument *)database
{
if (_database != database) {
_database = database;
[self useDocument];
}
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self useDocument];
//[self.collectionView reloadData];
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.5];
self.collectionView.alpha = 1;
[UIView commitAnimations];
}
Why if i come back and return the code work else is like that I didn't call the server for refresh the array?
Triy with this code:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Favorits" inManagedObjectContext:moc]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"title == %#", #"Some Title"];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *results = [moc executeFetchRequest:request error:&error];
YourObject *object = [results objectAtIndex:0];
object.title = #"Bla bla bla";
//save changes
[moc save:&error];
if (error) {
//Do something
}
this 2 link is helpful:
http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSFetchRequest_Class/NSFetchRequest.html
If I didn't misunderstand you, the problem is that when you refresh the array, your data is not updated.
If you reload from the DB and you haven't saved your changes, then you will get the values are in the DB. You should do:
NSError *saveError = nil;
[user.managedObjectContext save:&saveError];
if (error) {
//Do whatever
}
You should use this code before call again the function to reload the array from the DB. The place it's up to you, but if you only call to refresh the array from DB when you are loading the viewcontroller, you can save the data when you are leaving the viewController.
Related
I'm making a SpriteKit game and I need to save the player's score using Core Data. I have a property with int value that starts off as being set to "5" and increment it x amount of times. I save it then transition to a different scene and fetch it. It shows up un-incremented with the initial value of "5".
I'm new to Core Data so forgive me if this is a stupid question, but how can I get Core Data to take the incrementation in to account? Or Is information being lost when I reference the property and how can I prevent this?
self.score = 5;
self.score++
and then save by calling this method.
AppDelegate.m
-(void) createObject {
Score *scoreEntity = (Score *)[NSEntityDescription
insertNewObjectForEntityForName:#"Score"
inManagedObjectContext:self.managedObjectContext];
SpaceshipScene *spaceshipSceneReference = [[SpaceshipScene alloc] init];
id points = [NSNumber numberWithInteger: spaceshipSceneReference.score];
scoreEntity.points = points;
scoreEntity.playerName = #"Joe";
NSError *error = nil;
// Saves the managedObjectContext
if (! [[self managedObjectContext] save:&error] ) {
NSLog(#"An error! %#", error);
}
}
This is how I call it.
SpaceshipScene.m
AppDelegate *appDelegateReference = [[AppDelegate alloc] init];
[appDelegateReference createObject];
I then fetch it in another class/scene using this method
AppDelegate.m
-(void)fetchObject {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Score"inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Sort fetched data
NSSortDescriptor *sortByPoints = [[NSSortDescriptor alloc] initWithKey:#"points" ascending:NO];
// Put them in an array
NSArray *sortDescriptor = [[NSArray alloc] initWithObjects:sortByPoints, nil];
// Pass the array to the fetch request
[fetchRequest setSortDescriptors:sortDescriptor];
NSError *error = nil;
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
NSLog(#"Problem %#", error);
}
for (Score *s in fetchedObjects) {
NSLog(#" %# %d",s.playerName, [s.points integerValue]);
}
}
This is how I call it in the final scene/class
AppDelegate *appDelegateReference = [[AppDelegate alloc] init];
[appDelegateReference fetchObject];
Hope this will work, after fetching your Score entity , simply assign new values in it don't use insert object for update any value.
[scoreEntity setPoints:[NSNumber numberWithInteger: spaceshipSceneReference.score]];
[scoreEntity setPlayerName:#"Joe"];
then Save the values:
NSError *error = nil;
// Saves the managedObjectContext
if (! [[self managedObjectContext] save:&error] ) {
NSLog(#"An error! %#", error);
}
So i implemented Core Data Concurrency using http://www.cocoanetics.com/2012/07/multi-context-coredata/ i implemented separate private MOC for every object to input data, it works good, i have mainMOC on main thread fetching data using FRC, the only issue that i have faced so far is updating relationship entity.
so if i have Photographer & Photos entities one to many relationship "one photographer can have multiple photos", when user uploads new photo, i update photo entity and photographer "relationship" with the below code... 'note: this is a temp code'
+ (Photo *)didUploadNewPhoto:(PhotoClass *)photoObj inManagedObjectContext:(NSManagedObjectContext *)context
{
Photo *photo = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Photos"];
request.predicate = [NSPredicate predicateWithFormat:#"photoID = %#",photoObj.ID];
NSError *error;
NSArray *matches = [context executeFetchRequest:request error:&error];
if (!matches || error || ([matches count] > 1)) {
//handle error
} else if ([matches count]) {
photo = [matches firstObject];
} else {
photo.title = #"";
photo.timeStamp = #"";
photo.photographer = [Photographer updatePhotographerClass:photoObj inManagedObjectContext:context];
NSError *error = nil;
if (![context save:&error]) {
//handle Error
}
return photo;
}
+ (Photographer *)updatePhotographerClass:(Photo *)photoObj inManagedObjectContext:(NSManagedObjectContext *)context
{
Photographer *photographer = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Photographer"];
request.predicate = [NSPredicate predicateWithFormat:#"PhotographerID= %#",photoObj.PhotographerID];
NSError *error;
NSArray *matches = [context executeFetchRequest:request error:&error];
if (!matches || error || ([matches count] > 1)) {
//handle error
} else if ([matches count]) {
photographer = [matches firstObject];
photographer.didUploadPhoto = #YES;
}
return photographer;
}
The issue i'm facing is that FRC does update photo however, it doesn't update the boolean in Photographer "didUploadPhoto", is there something that I might be missing? if i use this same code using context on main thread, it works great... but if i change it to input data using background thread, it does update Photo but it doesn't update Photographer.
Update:
This is example code of how i call UploadPhoto method using background/private MOC
NSManagedObjectContext *tempContext = self.contextStore.newPrivateContext;
[tempContext performBlock:^{
[Photos didUploadNewPhoto:photoObj inManagedObjectContext:tempContext];
}];
and this is how i create privateContext
- (NSManagedObjectContext*)newPrivateContext
{
NSManagedObjectContext* context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.persistentStoreCoordinator = self.persistentStoreCoordinator;
[context setUndoManager:nil];
return context;
}
Here is the notification that i use to merge changes...
- (void)setupSaveNotification
{
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification
object:nil
queue:nil
usingBlock:^(NSNotification* note) {
NSManagedObjectContext *moc = self.mainContext;
if (note.object != moc) {
[moc performBlock:^(){
[moc mergeChangesFromContextDidSaveNotification:note];
}];
}
}];
}
I'm new to NSManagedObjectContext. I have created an entity Link in my app, which contains a NSString *url.
At some point of my app, I need to insert a new Link in my base, so I simply do this :
Link *link = [NSEntityDescription
insertNewObjectForEntityForName:#"Link"
inManagedObjectContext:self.managedObjectContext];
link.url = myUrl;
But before doing this, I want to check if there is not already a Link in my base with the same url. And I have no idea of how to do so... what should I do?
EDIT : to retrieve data from the base I'm using this method from a tool I found on the web:
// Fetch objects with a predicate
+(NSMutableArray *)searchObjectsForEntity:(NSString*)entityName withPredicate:(NSPredicate *)predicate andSortKey:(NSString*)sortKey andSortAscending:(BOOL)sortAscending andContext:(NSManagedObjectContext *)managedObjectContext
{
// Create fetch request
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
// If a predicate was specified then use it in the request
if (predicate != nil)
[request setPredicate:predicate];
// If a sort key was passed then use it in the request
if (sortKey != nil) {
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:sortAscending];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
}
// Execute the fetch request
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
// If the returned array was nil then there was an error
if (mutableFetchResults == nil)
NSLog(#"Couldn't get objects for entity %#", entityName);
// Return the results
return mutableFetchResults;
}
I would like to know how to use it.
Thanks for your help.
The method you provided just searches for a NSManagedObject that matches the attributes in the NSManagedObjectContext and if one exists, it returns it.
But, what you need to implement is called the Find-or-Create pattern, which is discussed in the Core Data programming guide. Basically, you search for an object matching specific criteria and if it exists that object is returned. If that object does not exist you create it.
Core Data Programming Guide
E.g.
+ (NSString *)entityName
{
return NSStringFromClass([Link class]);
}
+ (instancetype)findUsingPredicate:(NSPredicate *)predicate withContext:(NSManagedObjectContext *)context
{
Link * entity;
// Setup the fetchRequest
NSFetchRequest * fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[[self class] entityName]];
fetchRequest.predicate = predicate;
// Credit: #Martin R
[fetchRequest setFetchLimit:1];
// Execute the fetchRequest
NSError *error = nil;
NSArray * matchingLinks = [context executeFetchRequest:fetchRequest error:&error];
// MatchingLinks will only return nil if an error has occurred otherwise it will return 0
if (!matchingLinks)
{
// handle error
// Core data returns nil if an error occured
NSLog(#"%s %#", __PRETTY_FUNCTION__, [error description]);
}
else if ([matchingLinks count] <= 0)
{
// if the count <= 0, there were no matches
NSLog(#"%s Not found", __PRETTY_FUNCTION__);
} else {
// A link with a url that matches the url in the dictionary was found.
NSLog(#"%s Found", __PRETTY_FUNCTION__);
entity = [matchingLinks lastObject];
}
return entity;
}
+ (instancetype)findUsingPredicate:(NSPredicate *)predicate orCreateWithContext:(NSManagedObjectContext *)context
{
Link * entity = [[self class] findUsingPredicate:predicate withContext:context];
if (!entity) {
entity = [[self class] createWithContext:context];
}
return entity;
}
+ (isntancetype)createWithContext:(NSManagedObjectContext *)context
{
return [[self class] alloc] initWithContext:context];
}
- (instancetype)initWithContext:(NSManagedObjectContext *)context
{
Link * entity = [NSEntityDescription insertNewObjectForEntityForName:[[self class] entityName] inManagedObjectContext:context];
return entity;
}
USE CASE:
NSString * url = #"http://www.mylink.com";
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"url = %#", url];
Link * link = [Link findUsingPredicate:predicate orCreateWithContext:self.managedObjectContext];
link.url = url;
You can do it like this (with your method):
AppDelegate *del = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = del.managedObjectContext;
NSString *urlString = #"YOUR URL HERE";
NSMutableArray *fetchedResults = [self searchObjectsForEntity:#"Link" withPredicate:[NSPredicate predicateWithFormat:#"url == %#", urlString] andSortKey:#"url" andSortAscending:YES andContext:managedObjectContext];
BOOL exist = NO;
if(fetchedResults.count >= 1){
exist = YES;
}
I currently have a problem deleting an object in a to many relationship.
My app have the following relationship:
Product <<- Cart
When the user pushes a "add to cart" button in my viewcontroller, the following code is setting the relations between the product object and the cart
+ (Cart *)addProductToCartWithProduct:(Product *)product inManagedObjectContext:(NSManagedObjectContext *)context {
Cart *cart = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Cart"];
NSError *error = nil;
NSArray *carts = [context executeFetchRequest:request error:&error];
if (!carts || ([carts count] > 1)) {
// handle error
} else if (![carts count]) {
cart = [NSEntityDescription insertNewObjectForEntityForName:#"Cart" inManagedObjectContext:context];
} else { // they already have a cart started
cart = [carts lastObject];
}
/*Get Object ID to safely pass NSMangedObject between threads (A background worker thread and the main thread). */
NSManagedObjectID *retID = [product objectID];
[cart addProductsObject:(Product *)[context objectWithID:retID]];
//Inverse relationship
[(Product *) [context objectWithID:retID] setInCart:cart];
return cart;
}
This then returns a cart object, which I pass to my cart viewcontroller, and fetch the products in that relationship like so:
// Fetch request for "Product":
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Product"];
// Fetch only products for the cart:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"inCart = %#", self.cart];
[fetchRequest setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"navn" ascending:YES];
[fetchRequest setSortDescriptors:#[sortDescriptor]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_theManagedObjectContext sectionNameKeyPath:nil cacheName:nil];
_fetchedResultsController.delegate = self;
When I then try to delete an object from the relationship like so:
-(void)RemoveFromCart:(UIButton *)sender {
NSIndexPath *ip = [NSIndexPath indexPathForRow:sender.tag inSection:0];
Product *prod = (Product *)[self.fetchedResultsController objectAtIndexPath:ip];
prod.inCart = nil;
[_cart removeProductsObject:prod];
NSLog(#"Cart %# %#", _cart.products, prod);
[self saveCurrentContext:_theManagedObjectContext];
[self loadCart];
[_orderTable reloadData];
}
The product is removed visually (gone from the tableview/screen) because inCart is set to nil, but not technically... when I log the cart object, the product object is still in the relationship, so it seems like the [_cart removeProductsObject:prod]; is not working.
And it also doesn't work the other way around, when I try to add the same product to the cart, I just have deleted (from the cart), for some reason the inverse relationship "inCart" is not set, after I have set it to "nil", when the product object is removed.
Why is this happening? and how do I fix it? :).
EDIT:
Pictures showcasing inverse relationships in Core data model editor:
Pass Cart to other viewcontroller:
[[[DataManager sharedInstance] backgroundManagedObjectContext] performBlock:^{
UITabBarController *tabBarController = self.tabBarController;
for (UINavigationController *navController in tabBarController.viewControllers) {
for (UIViewController *vc in navController.viewControllers) {
if ([vc isMemberOfClass:NSClassFromString(#"CartViewController")]){
CartViewController *cartVC = (CartViewController *) vc;
cartVC.cart = [Cart addProductToCartWithProduct:prod inManagedObjectContext: [[DataManager sharedInstance] backgroundManagedObjectContext]];
[[DataManager sharedInstance] saveBackgroundContext];
[[DataManager sharedInstance] saveMasterContext];
NSLog(#" %#", cartVC.cart);
}
}
}
}];
Save Context
-(void)saveCurrentContext:(NSManagedObjectContext *)context {
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"NOT SAVED");
}
[[DataManager sharedInstance] saveBackgroundContext];
[[DataManager sharedInstance] saveMasterContext];
}
Okay, so I found a work around for this very weird problem.
Since the autogenerated accessor methods didn't work for some reason, I had to think of another way to delete the object from the relationship.
for (Product *prod in _cart.products) {
//To Very reliable to check for item by name attribute, but It works :)
if ([prod.name isEqualToString:product.name]) {
product = prod;
NSMutableSet *set = [NSMutableSet setWithSet:_cart.products];
[set removeObject:prod];
_cart.products = set;
}
}
I am creating a multi-user iPhone app, and I am trying to finish up the coding for the user login in process. I can successfully create an account, and store the data the user inputs into the Core Data DB, and the pin (password) into the Keychain, so now I am trying to complete the login process. The following code listed below is what I have so far, and I am wondering what I need to do to complete the login process.
- (IBAction)processLogin:(id)sender {
// hide keyboard
[_textFieldUsername resignFirstResponder];
[_textFieldPin resignFirstResponder];
// First - make activity indicator visible, then start animating, then turn of wrong user / pin label
_welcomeActivityIndicator.hidden = FALSE;
[_welcomeActivityIndicator startAnimating];
[_wrongUserPin setHidden:YES];
// check if username and pin text fields are populated
if ([_textFieldUsername.text length ] == 0 && [_textFieldPin.text length ] == 0)
{
[_welcomeActivityIndicator stopAnimating];
[_wrongUserPin setHidden:NO];
}
// CORE DATA
NSFetchRequest *request= [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Account" inManagedObjectContext:_managedObjectContext];
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"username=%#",self.textFieldUsername.text];
//check pin
Account *pinAccount = [[Account alloc] init];
[pinAccount.password isEqualToString:_textFieldPin.text];
[request setEntity:entity];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *array = [_managedObjectContext executeFetchRequest:request error:&error];
if (array != nil) {
NSUInteger count = [array count]; // may be 0 if the object has been deleted.
NSLog(#"Username may exist, %#",count);
}
else {
NSLog(#"Username does not exist.");
}
// TODO - put this in proper place - play audio bell if user logs in correctly
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"Glass", CFSTR("aiff"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
// TODO - put this in proper place - Load ViewControllerHome
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ViewControllerHome *home = (ViewControllerHome *)[storyboard instantiateViewControllerWithIdentifier:#"Home"];
[self presentModalViewController:home animated:YES];
}
The Account and AccountBase class files m and h look like the following:
Account.h http://pastie.org/4149299
Account.m http://pastie.org/4149296
AccountBase.h http://pastie.org/4149301
AccountBase.m http://pastie.org/4149302
I would appreciate any ideas or thoughts, and thanks for reading.
I was able to complete the login process with the following code.
- (IBAction)processLogin:(id)sender {
// hide keyboard
[_textFieldUsername resignFirstResponder];
[_textFieldPin resignFirstResponder];
// First - make activity indicator visible, then start animating, then turn of wrong user / pin label
_welcomeActivityIndicator.hidden = FALSE;
[_welcomeActivityIndicator startAnimating];
[_wrongUserPin setHidden:YES];
// check if username and pin text fields are populated
if ([_textFieldUsername.text length ] == 0 && [_textFieldPin.text length ] == 0)
{
[_welcomeActivityIndicator stopAnimating];
[_wrongUserPin setHidden:NO];
}
// CORE DATA
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Account" inManagedObjectContext:_managedObjectContext];
// set entity for request
[request setEntity:entity];
// filter results using a predicate
NSPredicate *pred =[NSPredicate predicateWithFormat:(#"username = %#"), _textFieldUsername.text];
// set predicate for the request
[request setPredicate:pred];
NSError *error = nil;
// store DB usernames in results array
NSArray *results = [_managedObjectContext executeFetchRequest:request error:&error];
NSLog(#"The returned results are %#",results);
// check text field against results stored in DB
for (Account *anAccount in results) {
if ([anAccount.username isEqualToString:_textFieldUsername.text]){
NSLog(#"Your username exists");
if ([anAccount.password isEqualToString:_textFieldPin.text]){
NSLog(#"Your pin is correct");
// TODO - put this in proper place - play audio bell if user logs in correctly
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"Glass", CFSTR("aiff"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
// TODO - put this in proper place - Load ViewController(Root)Home
if([anAccount.username isEqualToString:#"root"])
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ViewControllerRootHome *roothome = (ViewControllerRootHome *)[storyboard instantiateViewControllerWithIdentifier:#"rootHome"];
[self presentModalViewController:roothome animated:YES];
}
else {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ViewControllerHome *home = (ViewControllerHome *)[storyboard instantiateViewControllerWithIdentifier:#"Home"];
[self presentModalViewController:home animated:YES];
}
}
else {
NSLog(#"Your pin is wrong");
[_welcomeActivityIndicator stopAnimating];
[_wrongUserPin setHidden:NO];
}
}
else {
NSLog(#"Your username was not found");
[_welcomeActivityIndicator stopAnimating];
[_wrongUserPin setHidden:NO];
}
}
}
I believe your mis-using core data. It is not meant to be used like sqlite, always running always query-able. (http://cocoawithlove.com/2010/02/differences-between-core-data-and.html)
You are trying to keep a database of user but your also over complicating it. While in memory the app can use an NSMutableArray of your own objects to keep track of usernames, tabs
So you would have your class:
interface Alcoholic : NSObject
#property(nonatomic,retain)NSString * username;
#property(nonatomic,retain)NSString * pin;
#property(nonatomic,retain)NSString * tab;
#end
In the section of code that adds these it would have a mutable array
NSMutableArray * alcoholics = [[NSMutableArray alloc]init];
- (IBAction)processLogin:(id)sender {
int i = 0;
while (i<alcoholics.count)
{
Aloholic = [alcoholics objectAtIndex:i];
if(self.textFieldUsername.text == Aloholic.username)
NSLog(#"Username may exist, %#",count);
}
else {
NSLog(#"Username does not exist.");
}
}
etc...
Since Im sure your next question is how to make it persistent and thats where core data comes into play.
in your app delegate get the alcoholics array and save that to core data when the app opens and closes
-(void)save
{
//use core data to save needed data persitently
self.Values = [NSEntityDescription
insertNewObjectForEntityForName:#"processLoginClass"
inManagedObjectContext:[self managedObjectContext]];
self.Values.alcoholics = self.processLoginClass.alcoholics;
}
NSError *error;
if (![[self managedObjectContext] save:&error])
{
NSLog(#"Couldn't save state information: %#", [error localizedDescription]);
}
}
-(void)load
{
//use core data to load needed data
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Values"
inManagedObjectContext:[self managedObjectContext]];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
for (processLoginClass *info in fetchedObjects)
{
[self.processLoginClass setAlcholics:info.alcholics];
}
}