How do I edit the value of some field in CoreData entity (SQLite) by tapping to Button?
For example, in my UITableViewCell I have button. I would like this button to change the value of some boolean field. By tapping first time I would like to write YES and second time - NO.
1.Join is a manually created join table Ingredients<->>Join<<->Recipes
2._ingredientInfo contain only 1 record
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cellIngredient";
IngredientCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[IngredientCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
Ingredients *ingredient = [ingredientsArray_ objectAtIndex:indexPath.row];
cell.nameLabel.text = ingredient.name;
//Указываем что-то типа DataSource
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext;
if (context != nil) {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"inRecipe == %# AND ingredient == %#", self.recipe, ingredient];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Join" inManagedObjectContext:context];
[request setEntity:entity];
[request setPredicate:predicate];
NSError *error = nil;
NSMutableArray *mutableFetchResult = [[context executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResult == nil) {
NSLog(#"No fetched objects!!!");
abort();
}
_ingredientInfo = [mutableFetchResult objectAtIndex:0];
}
cell.countLabel.text = [NSString stringWithFormat:#"%#", _ingredientInfo.count];
if (_ingredientInfo.inCart == [NSNumber numberWithInt:0]) {
cell.toCartBtn.imageView.image = [UIImage imageNamed:#"runTo.png"];
}
else {
cell.toCartBtn.imageView.image = [UIImage imageNamed:#"inCart.png"];
}
cell.unitLabel.text = ingredient.units;
return cell;
}
and when I tap the button cell.toCartBtn
- (IBAction)toCart:(id)sender
{
if (_ingredientInfo.inCart == [NSNumber numberWithInt:0]) {
_ingredientInfo.inCart = [NSNumber numberWithInt:1];
}
else {
_ingredientInfo.inCart = [NSNumber numberWithInt:0];
}
NSError *error = nil;
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if ([appDelegate.managedObjectContext save:&error]) {
[self.ingredientsTableView reloadData];
}
else {
NSLog(#"Error updating");
}
}
First fetch your object to be modified
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"entityName" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"(id == %#)", eID]];
NSError *error;
NSArray *details = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
entityName *objEntity= nil;
//error handling goes here
if([details count] > 0)
objEntity = (entityName *)[details objectAtIndex:0];
Now update that entity as you insert it
if(objEntity){
club.fieldName = #"YES";
NSError *error = nil;
if(![self.managedObjectContext save:&error])
NSLog(#"Error updating");
}
Related
I am new in iPhone Application Development. I am working on chat app in iOS using XMPP and Ejabberd. But I am not able to delete the chat of particular user (not a single message).
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[self DeleteMessageChat:indexPath];
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[messages removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
}
-(void)DeleteMessageChat :(NSIndexPath *)indexpath
{
self.cls=[self.arrProfile objectAtIndex:indexpath.row];
NSString *userJid = [NSString stringWithFormat:#"%#%#",self.cls.UserId,Xmppserver];
XMPPMessageArchivingCoreDataStorage *storage = appDelegate.xmppMessageArchivingStorage;
NSManagedObjectContext *moc = [storage mainThreadManagedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject"
inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entityDescription];
NSString *predicateFrmt = #"bareJidStr == %#";
NSError *error;
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFrmt, userJid];
request.predicate = predicate;
NSArray *messages_new = [moc executeFetchRequest:request error:&error];
NSManagedObject *obj=[messages_new objectAtIndex:indexpath.row];
[moc deleteObject:obj];
error = nil;
if (![moc save:&error])
{
NSLog(#"Error deleting movie, %#", [error userInfo]);
}
}
Please help me to solved this problem.
I did this in my code. Try to edit according to you arrays.
NSString *userJid = [NSString stringWithFormat:#"%#%#",cell.frndName.text,DomainName];
NSString *userJid1= [NSString stringWithFormat:#"%#%#",[[NSUserDefaults standardUserDefaults]valueForKey:#"name"],DomainName];
NSFetchRequest *messagesCoreD = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context=[[self appDelegate].xmppMessageArchivingCoreDataStorage mainThreadManagedObjectContext];
NSEntityDescription *messageEntity = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Contact_CoreDataObject" inManagedObjectContext:context];
[messagesCoreD setEntity:messageEntity];
[messagesCoreD setIncludesPropertyValues:NO]; //only fetch the managedObjectID
NSString *predicateFrmt = #"bareJidStr == %#";
NSString *predicateFrmt1 = #"streamBareJidStr == %#";
NSPredicate *predicateName = [NSPredicate predicateWithFormat:predicateFrmt,userJid];
NSPredicate *predicateSSID = [NSPredicate predicateWithFormat:predicateFrmt1,userJid1];
NSArray *subPredicates = [NSArray arrayWithObjects:predicateName, predicateSSID, nil];
NSPredicate *orPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
messagesCoreD.predicate = orPredicate;
NSError * error = nil;
NSArray * messages = [context executeFetchRequest:messagesCoreD error:&error];
//error handling goes here
[tableView reloadData];
for (NSManagedObject * message in messages)
{
[context deleteObject:message];
[tableView reloadData];
}
NSEntityDescription *messageEntity1 = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject" inManagedObjectContext:context];
[messagesCoreD setEntity:messageEntity1];
[messagesCoreD setIncludesPropertyValues:NO]; //only fetch the managedObjectID
messagesCoreD.predicate = orPredicate;
NSArray * messages1 = [context executeFetchRequest:messagesCoreD error:&error];
//error handling goes here
[tableView reloadData];
for (NSManagedObject * message in messages1)
{
[context deleteObject:message];
[tableView reloadData];
}
NSError *saveError = nil;
[context save:&saveError];
I added this code in commitEditingStyle delegate method. Here you pass friend name in userJid and logged in user name in userJid1.
I am Using core data as my data base. Inside my UITableView I have a button to add projects , But at this moment I only Use it to add names. But the names I add do not display on the tableview.
I think my problem is that I need to repopulate my projectArray, how and where do I do that.
Here is my code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_projectArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Project* project = _projectArray[indexPath.row];
static NSString *cellID = #"TableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];
cell.textLabel.text = project.name;
cell.detailTextLabel.text = #"prooo";
self.tableView.delegate = self;
self.tableView.dataSource = self;
return cell;
}
Here is my button code:
- (IBAction)addProjectButton:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Enter new project name."
message:nil
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
UITextField *textField = [alert textFieldAtIndex:0];
textField.placeholder = #"Project Name";
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex != alertView.cancelButtonIndex) {
UITextField *field = [alertView textFieldAtIndex:0];
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = [delegate managedObjectContext];
NSManagedObject *object =[NSEntityDescription insertNewObjectForEntityForName:#"Project" inManagedObjectContext:context];
[object setValue:field.text forKey:#"name"];
NSError *error;
[context save:&error];
if (![context save:&error]) {
NSLog(#"Whoops %# %#", error, [error localizedDescription]);
}
[self.tableView reloadData];
} else {
NSLog(#"cancel");
}
}
And here is my ViewWillAppear Code , where I fetch info:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:nil];
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = [delegate managedObjectContext];
//load project
NSFetchRequest *fetch = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Project" inManagedObjectContext:context];
[fetch setEntity:entity];
NSError *error;
_projectArray = [context executeFetchRequest:fetch error:&error];
}
There are many things you can do. To make it a good code, I will suggest write a method that reloads your array. Like this
-(void) reloadArray
{
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = [delegate managedObjectContext];
//load project
NSFetchRequest *fetch = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Project" inManagedObjectContext:context];
[fetch setEntity:entity];
NSError *error;
_projectArray = [context executeFetchRequest:fetch error:&error];
}
Then replace your viewDidAppear like this -
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:nil];
[self reloadArray];
}
Also in your numberOfSectionsInTableView: method, make this change -
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
[self reloadArray];
return 1;
}
And it should do the magic...
Have you set the dataSource and delegate properties of tableView?
self.tableView.delegate = self;
self.tableView.dataSource = self;
Change This :
NSFetchRequest *fetch = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Project" inManagedObjectContext:context];
[fetch setEntity:entity];
NSError *error;
_projectArray = [context executeFetchRequest:fetch error:&error];
To:
_projectArray = [[NSMutableArray alloc]init];
NSFetchRequest *fetch = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Project" inManagedObjectContext:context];
[fetch setEntity:entity];
NSManagedObject *object = nil;
NSError *error;
NSArray *result = [context executeFetchRequest:fetch error:&error];
for (int i = 0; i < [result count]; i ++) {
object = [result objectAtIndex:i];
[_projectArray setObject:[object valueForKey:#"name"]
}
I am parsing data from JSON and Storing to CoreData in the same time i am displaying the the data to tableview but the problem i am having is data is displaying only after download completed but i dont want like this i want to download the data in background and display the data while downloading is processed also how can i do this
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
arrayData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSError *error;
NSManagedObjectContext *context = [appDelegate managedObjectContext];
context = [appDelegate managedObjectContext];
for (int i = 0; i < [arrayData count]; i++) {
idNum = [arrayData objectAtIndex:i][#"id"];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Discount"];
[request setPredicate:[NSPredicate predicateWithFormat:#"cID = %#",idNum]];
[request setFetchLimit:1];
NSUInteger count = [context countForFetchRequest:request error:&error];
if (count == NSNotFound) {
NSLog(#"ERROR");
}else if (count == 0) {
NSLog(#"New Data Coming");
name = [arrayData objectAtIndex:i][#"name"];
summary = [arrayData objectAtIndex:i][#"summary"];
region = [arrayData objectAtIndex:i][#"region"];
imageURL = [arrayData objectAtIndex:i][#"images"][#"logo"];
id benefits1 = [arrayData objectAtIndex:i][#"benefits"];
benefiteString = [NSString stringWithFormat:#"%# %#",[benefits1 objectAtIndex:0][#"key"],[benefits1 objectAtIndex:0][#"value"]];
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];
dateUpdate = [arrayData objectAtIndex:i][#"updated_at"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat: #"yyyy-MM-dd'T'HH:mm:ss.sssZ"];
NSDate *date =[dateFormatter dateFromString:dateUpdate];
[dateFormatter setDateFormat:#"yyyy/MM/dd HH:mm:ss"];
NSLog(#"DAte : %#",date);
Discount * d = [NSEntityDescription insertNewObjectForEntityForName:#"Discount" inManagedObjectContext:context];
d.name = name;
d.summary = summary;
d.regions = region;
d.cID = idNum;
d.imageLogo = data;
d.updated_at = date;
d.benefits = benefiteString;
if (![context save:&error]) {
NSLog(#"Getting error while saving data");
}
else{
NSLog(#"Saved");
}
}
}
[sharedAppDelegate dismissGlobalHUD];
[listTableView reloadData];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_myArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
customCellClass = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (customCellClass == nil)
{
customCellClass = [[CellCustom alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
customCellClass.nameLabel.text = [[_myArray objectAtIndex:indexPath.row]name];
customCellClass.cityLabel.text =[[_myArray objectAtIndex:indexPath.row]regions];
customCellClass.detailLabel.text = [[_myArray objectAtIndex:indexPath.row]summary];
NSData * d = [[_myArray objectAtIndex:indexPath.row]imageLogo];
customCellClass.mainImage.image = [UIImage imageWithData:d];
customCellClass.benefitsLabel.text = [[_myArray objectAtIndex:indexPath.row]benefits];
[sharedAppDelegate dismissGlobalHUD];
return customCellClass;
}
-(void)dataDidSave
{
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Discount" inManagedObjectContext:context]; [fetchRequest setEntity:entity];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *result = [context executeFetchRequest:fetchRequest error:&error];
self.myArray = result;
[listTableView reloadData];
}
-(void)viewWillAppear:(BOOL)animated
{
[sharedAppDelegate showGlobalProgressHUDWithTitle:#"Loading..."];
[self dataDidSave];
}
In connectionDidFinishLoading: try something like this:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^ {
// Process your data and then incrementally call
dispatch_async(dispatch_get_main_queue(),^ {
[listTableView reloadData];
});
}
});
I am using Core Data and UITableViewController. I have a table category with columns name, descript and is_active (boolean).
I want to fetch results like
SELECT *
FROM CATEGORY
WHERE IS_ACTIVE = 1
I have made this active through a form.
I am trying this code - in view I have this load section
- (void)viewDidLoad
{
[super viewDidLoad];
IMSAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
context = [appDelegate managedObjectContext];
NSEntityDescription *category = [NSEntityDescription entityForName:#"Category" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:category];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSArray *srotDesc = [[NSArray alloc]initWithObjects:sort, nil];
[request setSortDescriptors:srotDesc];
NSError *error;
NSMutableArray *results = [[context executeFetchRequest:request error:&error] mutableCopy];
if (results == nil) {
//error handle here
}
[self setArr:results];
NSLog(#"there is category array");
[self.tableView reloadData];
[arr count];
}
And In tableViewCell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Category *category = [arr objectAtIndex:indexPath.row];
// Configure the cell...
cell.textLabel.text = [category name];
cell.detailTextLabel.text = [category descript];
return cell;
}
It is showing all the records to me like all the name and the description.
I want to show those records only where is_active = 1.
Add a predicate to your NSFetchRequest
...
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:category];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"is_active == 1"];
[request setPredicate:predicate];
...
I have a Core Data to-many relationship that looks like this:
Athlete(evals)<->>Eval(whosEval)
I have a table view for Athletes which displays ALL the Athletes in the database. I want to set the subtitle text to a Eval attribute, let's say it is called "date_recorded" the problem is, there could be more than 1 eval for each Athlete. I need to select the last object in the evalArray, and then display the correlating Eval attribute for each Athlete, so each Athlete's subtitle text will probably be different. How would I do this for every cell in my table? Here is what i've got so far:
allathletes.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Athlete Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Athlete *athlete = (Athlete *)[athleteArray objectAtIndex:indexPath.row];
cell.textLabel.text =[athlete full];
cell.detailTextLabel.text = //eval attribute "date_recorded"
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
_managedObjectContext = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSFetchRequest *athleteRequest = [[NSFetchRequest alloc] init];
[athleteRequest setEntity:[NSEntityDescription entityForName:#"Athlete" inManagedObjectContext:_managedObjectContext]];
NSError *athleteError = nil;
NSPredicate *athletePredicate = [NSPredicate predicateWithFormat:#"full == %#", athlete.full];
[athleteRequest setPredicate:athletePredicate];
NSArray *results = [_managedObjectContext executeFetchRequest:athleteRequest error:&athleteError];
Athlete *currentAthlete = [results objectAtIndex:0];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"whosEval == %#", currentAthlete];
[request setPredicate:predicate];
NSEntityDescription *eval = [NSEntityDescription entityForName:#"Eval" inManagedObjectContext:_managedObjectContext];
[request setEntity:eval];
NSSortDescriptor *sortDescriptor =
[[NSSortDescriptor alloc] initWithKey:#"date_recorded"
ascending:NO
selector:#selector(localizedCaseInsensitiveCompare:)];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[_managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil){
//handle error
}
NSMutableArray *lastEvalArray = mutableFetchResults;
Eval *lastEval = lastEvalArray.lastObject;
cell.detailTextLabel.text = lastEval.date_recorded;
return cell;
}
If date_recorded is an NSDate attribute, then you can just do
Athlete *athlete = (Athlete *)[athleteArray objectAtIndex:indexPath.row];
NSDate *lastRecorded = [athlete valueForKeyPath:#"#max.evals.date_recorded"];
and then use a NSDateFormatter to convert lastRecorded to an NSString and
assign it to cell.detailTextLabel.text.