How to delete particular user's chat from XMPP server in iOS? - ios

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.

Related

coredata issue fetching data

I am getting only last record from coredata? below is the my code .
NSManagedObjectContext *context = ((AppDelegate*)[[UIApplication sharedApplication] delegate]).persistentContainer.viewContext;
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:#"Company"
inManagedObjectContext:context];
[object setValue:#"infosys" forKey:#"cname"];
[object setValue:#"01" forKey:#"compID"];
[object setValue:#"Pune" forKey:#"locaation"];
[object setValue:#"wipro" forKey:#"cname"];
[object setValue:#"02" forKey:#"compID"];
[object setValue:#"Mumbai" forKey:#"locaation"];
NSError *error;
if (![context save:&error]) {
NSLog(#"Failed to save - error: %#", [error localizedDescription]);
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Company" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *result = [context executeFetchRequest:fetchRequest error:&error];
if (result.count<=0) {
NSLog(#"No User Found");
}
else{
NSString *cname;
NSString *compID;
NSString *locaation;
for (NSManagedObject *obj in result) {
cname=[obj valueForKey:#"cname"];
compID=[obj valueForKey:#"compID"];
locaation=[obj valueForKey:#"locaation"];
}
NSLog(#"Store Data = %#",[NSString stringWithFormat:#"%# %# %#",cname,compID,locaation]);
}
Add objects like this,
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:#"Company" inManagedObjectContext:context];
[object setValue:#"infosys" forKey:#"cname"];
[object setValue:#"01" forKey:#"compID"];
[object setValue:#"Pune" forKey:#"locaation"];
NSManagedObject *object2 = [NSEntityDescription insertNewObjectForEntityForName:#"Company" inManagedObjectContext:context];
[object2 setValue:#"wipro" forKey:#"cname"];
[object2 setValue:#"02" forKey:#"compID"];
[object2 setValue:#"Mumbai" forKey:#"locaation"];
NSError *error;
if (![context save:&error]) {
NSLog(#"Failed to save - error: %#", [error localizedDescription]);
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Company" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *result = [context executeFetchRequest:fetchRequest error:&error];
if (result.count<=0) {
NSLog(#"No User Found");
}
else{
NSString *cname;
NSString *compID;
NSString *locaation;
for (NSManagedObject *obj in result) {
cname=[obj valueForKey:#"cname"];
compID=[obj valueForKey:#"compID"];
locaation=[obj valueForKey:#"locaation"];
NSLog(#"Store Data = %#",[NSString stringWithFormat:#"%# %# %#",cname,compID,locaation]);
}
}

Core data - Data fetching

I am using storyboard and and coredata in my app. In the home screen i want to list all my audio file details and in a button click i want to navigate to another screen and record a new file and save that file in database. When pressing back button i reached to home screen and i want to display the saved audio files in a tableview. Table row count is showing correctly. But the audio details are not correct. But when i stop and rebuild the app it is showing correctly. I wrote the code for reloading the tableview in viewWillApper.
- (void)viewWillAppear:(BOOL)animated
{
[tableview reloadData];
[self loadFiles];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"AudioDetails" inManagedObjectContext:managedObjectContext]];
[request setIncludesSubentities:NO]; NSError *err;
NSUInteger count = [managedObjectContext countForFetchRequest:request error:&err];
return count;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"AudioCell";
AudioCell *cell = (AudioCell *)[tableViewdequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (AudioCell *)[nibArray objectAtIndex:0];
[cell configurePlayerButton];
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"AudioDetails" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *info in fetchedObjects) {
if(audionames == nil)
audionames = [[NSMutableArray alloc] init];
[audionames addObject:[info valueForKey:#"audioName"]];
//NSManagedObject *details = [info valueForKey:#"details"];
//NSLog(#"Zip: %#", [details valueForKey:#"zip"]);
}
cell.titleLabel.text = [audionames objectAtIndex:indexPath.row];
return cell;
}
- (IBAction)SaveRecordingBtnClicked:(id)sender {
NSString *soundFilePath = [[self getDocumentDirectoryPath]
stringByAppendingPathComponent:OrginalAudioFileName];
NSURL *path=[NSURL URLWithString:soundFilePath];
NSError *error = nil;
AVAudioPlayer* avAudioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:path error:&error];
NSManagedObjectContext *context = [self managedObjectContext];
AudioDetails *audioDetails = [NSEntityDescription
insertNewObjectForEntityForName:#"AudioDetails"
inManagedObjectContext:context];
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:soundFilePath error:&error];
NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
NSDate *fileCreationDate = [fileAttributes objectForKey:NSFileCreationDate];
int duration = avAudioPlayer.duration;
[audioDetails setValue:[NSString stringWithFormat:#"%#",OrginalAudioFileName] forKey:#"audioName"];
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
}

How to fetch the result with proper query, wants to get isolated records?

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

Access value of an entity attribute

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.

How to edit the value of some attribute in entity?

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");
}

Resources