Program crashing after trying to read a NSString - ios

My program:
I have view parentView and childView. childView has a UITextField. This UITextField is completed by the user. Then UITextField.text is passed as a NSString to parentView via a NSNotificationCenter. The NSLog in the Notification method shows that the value has been passes successfully to parentView.
Now the issue.... when I try to access _guideDescription (that contains the value being passed) in the saveIntoExisting my app crashes. I dont understand why is crashing when it was able to retrieve the value in the notification method.
There is no error just (llbs).
Anyone has an idea why is this happening?
- (void)viewWillAppear:(BOOL)animated {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(notificationSelectedDescription:)
name:#"selectedDescription"
object:nil];
}
- (void) notificationSelectedDescription:(NSNotification *)notification {
_guideDescription = [[notification userInfo] valueForKey:#"selected"];
NSLog(#"Show me: %#",[_guideDescription description]);
}
- (IBAction)createExercise:(UIButton *)sender {
if (![self fetch]) {
NSLog(#"It doesnt exist already");
[self save];
} else {
NSLog(#"It does exist already");
/*
* ADD CODE ON HOW TO ACT WHEN EXISTS
*/
[self saveIntoExisting];
}
}
- (void) saveIntoExisting {
NSLog(#"saveintoExisting 1");
NSLog(#"saveintoExisting show me: %#",[_guideDescription description]);
NSFetchRequest *fetchExercise = [[NSFetchRequest alloc] init];
NSEntityDescription *entityItem = [NSEntityDescription entityForName:#"Exercise" inManagedObjectContext:context];
[fetchExercise setEntity:entityItem];
[fetchExercise setPredicate:[NSPredicate predicateWithFormat:#"exerciseName == %#",_originalExerciseName]];
[fetchExercise setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects:#"User", nil]];
fetchExercise.predicate = [NSPredicate predicateWithFormat:#"user.email LIKE %#",_appDelegate.currentUser];
NSError *error = nil;
NSArray* oldExercise = [[context executeFetchRequest:fetchExercise error:&error] mutableCopy];
Exercise *newExercise = (Exercise*) oldExercise[0];
newExercise.exerciseName = _exerciseName.text;
newExercise.exercisePic = _selectedImage;
if (![_guideDescription isEqualToString:#""]) {
newExercise.exerciseDescription =_guideDescription;
}
if (_youTubeLink){
newExercise.youtube =_youTubeLink;
}
if (![_selectRoutine.titleLabel.text isEqualToString:#"add to routine"]) {
newExercise.routine = [[self getCurrentRoutine] exercise];
[[self getCurrentUser] addRoutines:[[self getCurrentRoutine] exercise]];
}
[[self getCurrentUser] addExercisesObject:newExercise];
error = nil;
[context save:&error ];
}

The problem is probably that that _guideDescription string already is deallocated when you try to access it in -saveIntoExisted. You are now doing
_guideDescription = [[NSString alloc] initWithString:[[notification userInfo] valueForKey:#"selected"]];
and that works, but I would recommend:
[_guideDescription retain];
That makes sure the system doesn't deallocate the string.

Related

IOS/Objective-C: Location pins (json) not showing up after application first launch

My app receives a json object the first time is executed (with three pin point locations); there is a mapKit (the first screen) and a TableView where the user can check those locations. The issue is that when I first launch the app, there are no pins on the map. But if I switch to the table I can see them - on the cells - and if I switch again to the map, the pins appear...I don't Know why this happens, shouldn't I see the pins right after the app launch? The Map code:
- (void)viewDidLoad {
[super viewDidLoad];
NSNotificationCenter *notification=[NSNotificationCenter defaultCenter];
[notification addObserver:self selector:#selector (receiveNotification:) name:#"notification" object:self];
_mapView.showsUserLocation=YES;
_mapView.showsBuildings=YES;
_locationManager = [[CLLocationManager alloc] init];
[_locationManager requestAlwaysAuthorization];
_mapView.delegate = self;
_locationManager.delegate=self;
}
-(void)viewDidAppear:(BOOL)animated{
[self receiveNotification:nil];
}
-(void)receiveNotification:(NSNotification*)notification{
NSArray *spots = [Spot spotType:#"users"];
NSArray *places = [Spot spotWithType:#"users"];
[_mapView addAnnotations:spots];
[_mapView addAnnotations:places];
}
And the table:
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.dataSource = self;
self.detailList=#[#"Your Favourite Spots",#"Our suggestion"];
}
-(void)viewDidAppear:(BOOL)animated{
_lisbonSpots = [[Spot spotType:#"users"]mutableCopy];
_users=[[Spot spotWithType:#"users"]mutableCopy];
[self.tableView reloadData];
}
EDIT - The Spot Class
#implementation Spot
#dynamic ID;
#dynamic name;
#dynamic desc;
#dynamic type;
#dynamic phone;
#dynamic latitude;
#dynamic longitude;
+ (instancetype)spotWithName:(NSString *)name andCoord:
(CLLocationCoordinate2D)coord type:(NSString*)type desc:(NSString*)desc phone:(NSString*)phone{
NSPersistentContainer *persistenceContainer = [AppDelegate sharedDelegate].persistentContainer;
NSManagedObjectContext *context = persistenceContainer.viewContext;
Spot *spot = [NSEntityDescription insertNewObjectForEntityForName:#"Spot" inManagedObjectContext:context];
spot.name = name;
spot.latitude = coord.latitude;
spot.longitude = coord.longitude;
spot.type=type;
spot.desc=desc;
spot.phone=phone;
[[AppDelegate sharedDelegate] saveContext];
return spot;
}
+ (instancetype)spotWithDict:(NSDictionary *)dict {
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake([dict[#"latitude"] doubleValue], [dict[#"longitude"] doubleValue]);
return [Spot spotWithName:dict[#"name"] andCoord:coord type:dict[#"type"] desc:dict[#"desc"] phone:dict[#"phone"]];
}
+ (NSArray*)getSpotType:(NSString*)type withPredicate:(NSString*) pred andMessage:(NSString*)message {
NSPersistentContainer *persistenceContainer = [AppDelegate sharedDelegate].persistentContainer;
NSPredicate* predicate = [NSPredicate predicateWithFormat:pred, type];
NSManagedObjectContext *context = persistenceContainer.viewContext;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Spot"];
[request setPredicate:predicate];
NSError *error;
NSArray *result = [context executeFetchRequest:request error:&error];
if (error != nil) {
NSLog(message, [error localizedDescription]);
return nil;
}
return result;
}
+ (NSArray*)spotType:(NSString*)type {
return [Spot getSpotType:type withPredicate:#"type =%#" andMessage:#"[Spot spotType] -> %#"];
}
+ (NSArray*)spotWithType:(NSString*)type {
return [Spot getSpotType:type withPredicate:#"NOT (type = %#)" andMessage:#"[Spot spotWithType] -> %#"];
}
- (CLLocationCoordinate2D)coordinate {
return CLLocationCoordinate2DMake(self.latitude, self.longitude);
}
- (NSString *)title {
return self.name;
}
- (NSString *)description {
return [NSString stringWithFormat:#"%#", self.name];
}
#end
EDIT: The SpotService class
#implementation SpotService
+ (NSURL *)serviceURL {
return [NSURL URLWithString:#"http://training.reativ.io/ios/lisbon-spots"];
}
+ (BOOL)service:(id<SpotServiceInvoker>)invoker {
NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[SpotService serviceURL]];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error != nil) {
NSLog(#"Response: %#", response);
NSLog(#"Error: %#", error);
return;
}
NSArray *lisbonSecrets = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
if ([invoker respondsToSelector:#selector(receiveSpot:)]){
[invoker receiveSpot:lisbonSecrets];
}
for(NSDictionary *dict in lisbonSecrets) {
[Spot spotWithDict:dict];
}
});
}];
[task resume];
return YES;
}
My guess is - your Spot class retrieve data asynchronously and when you call [Spot spotType:#"users"] for the first time from viewDidAppear on your MapView there is no data retrieved yet. When you switch view controller the data appears and the everything works smoothly.
But it's better to show us your Spot class. Probably your need a completion handler or something like this to achieve expected behaviour.
Also, you call addAnnotations every time when your map appears on the screen and it means that MKMapView will add a copy of the annotations each time your call this methods. It's better to add additional checks to be sure that you do not add the same annotations more than once.

Not able to scroll and select cells displayed in uisearch controller

I have a screen which shows favourite locations and if a user wants to add new location he can search using uisearchcontroller and add it to favourite location's list.
The problem is that once i make the api call for autocomplete the list of searched locations is visible but i cannot select or scroll the table.
I know that the problem is where i set the uisearchcontroller. but i do not know the right way to do it.
I am newbie in iOS so ur suggestions will be welcome.
the following is the GithubRepository for the project(incase ul want to try out the app and make suggestions)
and heres the related code where i beleive the problem exists.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
favList = [[NSMutableArray alloc] init];
searchList = [[NSMutableArray alloc]init];
self.table.dataSource = self;
self.table.delegate = self;
[self initSearch];
}
#pragma mark UI Search methods
-(void) initSearch
{
FavouriteViewController *searchResultsController = [[FavouriteViewController alloc] init];
searchResultsController.table.dataSource = self;
searchResultsController.table.delegate = self;
searchResultsController.table.allowsSelectionDuringEditing = YES;
searchResultsController.table.allowsSelection = YES;
self.search = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];
self.definesPresentationContext = NO;
self.table.tableHeaderView = self.search.searchBar;
self.search.searchResultsUpdater = self;
self.search.searchBar.delegate = self;
self.search.dimsBackgroundDuringPresentation = NO;
}
didSelectRowAtIndex method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.search.active) {
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObjectModel *place = [NSEntityDescription insertNewObjectForEntityForName:#"Place" inManagedObjectContext:context];
NSString *places =[searchList[indexPath.row] valueForKey:#"name"];
if (![favList containsObject:places])
{
NSString *lati = [searchList[indexPath.row] valueForKey:#"lat"];
NSString *longi = [searchList[indexPath.row] valueForKey:#"lon"];
if (places != NULL && lati != NULL && longi != NULL)
{
[place setValue:places forKey:#"placeName"];
[place setValue:lati forKey:#"latitude"];
[place setValue:longi forKey:#"longitude"];
}
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
}
[self.search setActive:NO];
filtered = NO;
[self getalldata];
[self.table reloadData];
}
else
{
NSManagedObject *device = [favList objectAtIndex:indexPath.row];
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.SJI.Weather-App"];
[defaults setObject:[device valueForKey:#"placeName"] forKey:#"favSet"];
[[self navigationController] popToRootViewControllerAnimated:YES];
}
}

Why does Core Data fetch request return empty from custom UITableViewCell?

I have a method in ViewController.m called getData which is called inside viewDidLoad:
-(void)getData {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"WorkoutHasExercise" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
request.resultType = NSDictionaryResultType;
request.propertiesToFetch = [NSArray arrayWithObjects:#"exerciseName", #"reps", #"sets", nil];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(workoutName = %#)", _workoutName];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if ([objects count] == 0) {
} else {
[_exercises removeAllObjects];
for (int x = 0; x < [objects count]; x++) {
matches = objects[x];
[_exercises addObject:[matches valueForKey:#"exerciseName"]];
[_totalSets addObject:[matches valueForKey:#"sets"]];
[_totalReps addObject:[matches valueForKey:#"reps"]];
[_currentSets addObject:[NSNumber numberWithInteger:0]];
}
}
[_exercisesTableView reloadData];
}
I also have a custom UITableViewCell with two buttons initiated in cellForRowAtIndexPath:
ActiveWorkoutCell *cell = (ActiveWorkoutCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ActiveWorkoutCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.increaseButton.tag = indexPath.row;
cell.decreaseButton.tag = indexPath.row;
In ActiveWorkoutCell.m I have 2 IBActions for the buttons:
- (IBAction)decreaseSets:(id)sender {
ActiveWorkoutViewController *vc = [[ActiveWorkoutViewController alloc] init];
[vc decreaseSets:[sender tag]];
}
- (IBAction)increaseSets:(id)sender {
ActiveWorkoutViewController *vc = [[ActiveWorkoutViewController alloc] init];
[vc increaseSets:[sender tag]];
}
The IBActions call these 2 methods back in ViewController.m
-(void)increaseSets:(NSInteger)row {
[self getData];
//There will be code here to increase the value of currentSets[row]
}
-(void)decreaseSets:(NSInteger)row {
[self getData]
//Code to decrease value...
}
PROBLEM:
When getData is called from viewDidLoad, it works fine.
The problem occurs when returning to ViewController.m from the IBAction in ActiveWorkoutCell.m.
When I call [self getData] in increaseSets the fetch request returns an empty array. This is what is confusing me - the code works fine when it is first called but not at all when called the second time after the custom cell Action has been triggered.
Here is my viewDidLoad if it helps:
- (void)viewDidLoad {
[super viewDidLoad];
_exercises = [NSMutableArray array];
_totalSets = [NSMutableArray array];
_currentSets = [NSMutableArray array];
_totalReps = [NSMutableArray array];
_titleLabel.text = _workoutName;
_exercisesTableView.allowsSelection = NO;
[self getData];
}
_workoutName is given a value in prepareForSegue in the previous view controller.
I think I found the issue. You are instantiating the "ActivityWorkOutViewController" when the IBAction methods called and it will be a new instance and then in those methods you are calling [self getData] which pointing to the new instance which has no variables instantiated or viewDidLoad happened, so your mutable arrays are not allocated and hence they are empty.
Just use the old instance of the class to get the data.
I am not sure how you are referencing those classes. I am just in a confusion about that. But, you might check the allocations and calling the right class to get the data

Core data how update a record?

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.

iOS - How to create a login process using keychain / Core Data?

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];
}
}

Resources