I am new to xmpp , i need to store and show the chat history of users . i am getting the full history while using the below code.I only need the chat history of the selected user.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
XMPPMessageArchivingCoreDataStorage *xmppMessageArchivingCoreDataStorage=[XMPPMessageArchivingCoreDataStorage sharedInstance];
NSManagedObjectContext *context = [xmppMessageArchivingCoreDataStorage mainThreadManagedObjectContext];
NSEntityDescription *messageEntity = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject" inManagedObjectContext:context];
fetchRequest.entity = messageEntity;
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"timestamp" ascending:YES];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:fetchRequest error:&error];
[self print:[[NSMutableArray alloc]initWithArray:results]];
How can i get the chat history of a particular user,. i have searched a lot but couldnt got a success
Try this
- (void)loadChatHistoryWithUserName:(NSString *)userName
{
NSString *userJid = [NSString stringWithFormat:#"%##%#",userName,self.hostName];
NSManagedObjectContext *moc = [_xmppMsgStorage mainThreadManagedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject"
inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entityDescription];
NSError *error;
NSString *predicateFrmt = #"bareJidStr == %#";
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFrmt, userJid];
request.predicate = predicate;
NSArray *messages = [moc executeFetchRequest:request error:&error];
}
Related
I have stored dictionary in the transformable attribute.I want to know
How to get single data from it?**
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]
initWithEntityName:#"MemberProfile"];
NSSortDescriptor *ordering = [[NSSortDescriptor alloc] initWithKey:
[member.member_Profile objectForKey:"#order"] ascending:YES];
[fetchRequest setSortDescriptors:[NSArray
arrayWithObjects:ordering,nil]];
NSArray *result = [self.managedObjectContext
executeFetchRequest:fetchRequest error:Nil];
self.masterList = [[NSMutableArray alloc] initWithArray:result];
Import NSManagedObject(InstallProject) and fetch one object like this,
-(InstallProject *)readSelectedInstall:(NSString *)projIDString
{
NSArray *fetchedObjects;
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"InstallProject" inManagedObjectContext: context];
[fetch setEntity:entityDescription];
[fetch setPredicate:[NSPredicate predicateWithFormat:#"(ANY ProjID contains[cd] %#)",projIDString]];
NSError * error = nil;
fetchedObjects = [context executeFetchRequest:fetch error:&error];
if([fetchedObjects count] == 1)
return [fetchedObjects objectAtIndex:0];
else
return nil;
}
I have 1-many relationship and I am successfully putting data into it. The problem is that I am not able to fetch it out via the relationship attribute.
My ADD Code:
NSManagedObjectContext *context = [[CBICoreDataController sharedInstance] masterManagedObjectContext];
NSManagedObject *orders = [NSEntityDescription
insertNewObjectForEntityForName:#"UnsyncedOrders"
inManagedObjectContext:context];
[orders setValue:[dictionary valueForKey:#"specialInstructions"] forKey:#"specialInstructions"];
[orders setValue:[dictionary valueForKey:#"poNumber"] forKey:#"poNumber"];
[orders setValue:[dictionary valueForKey:#"specialInstructions"] forKey:#"specialInstructions"];
[orders setValue:[dictionary valueForKey:#"deliveryDate"] forKey:#"deliveryDate"];
[orders setValue:[dictionary valueForKey:#"account"] forKey:#"account"];
NSMutableSet *muteSet=[orders mutableSetValueForKey:#"items"];
for (NSDictionary *dict in [dictionary valueForKey:#"items"]) {
NSManagedObject *items = [NSEntityDescription
insertNewObjectForEntityForName:#"UnsyncedOrderItems"
inManagedObjectContext:context];
[items setValue:[dict valueForKey:#"arraykey"] forKey:#"arrayKey"];
//Other Sets Here
[muteSet addObject:items];
}
[orders setValue:muteSet forKey:#"items"];
NSError *error;
if (![context save:&error]) {
NSLog(#"Error saving in writeToMenuCostingDetailsTable: %#", [error localizedDescription]);
}
What I have for the fetch now but it does not work:
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"arrayKey" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSEntityDescription *parent = [NSEntityDescription entityForName:#"UnsyncedOrders"
inManagedObjectContext:context];
NSEntityDescription *child = [NSEntityDescription entityForName:#"UnsyncedOrderItems"
inManagedObjectContext:context];
[fetchRequest setEntity:child];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"orders == %#", parent];
[fetchRequest setPredicate:predicate];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
NSError *error;
[aFetchedResultsController performFetch:&error];
NSArray *fetchedObjects = [aFetchedResultsController fetchedObjects];
Your orders relationship relates to a specific instance of UnsyncedOrders. However when you try to perform a fetch, you do this:
NSEntityDescription *parent = [NSEntityDescription entityForName:#"UnsyncedOrders"
inManagedObjectContext:context];
[...]
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"orders == %#", parent];
[fetchRequest setPredicate:predicate];
You're trying to fetch instances where the orders relationship points to the UnsyncedOrders entity itself, not those that relate to a specific instance of UnsyncedOrders. That's always going to fail. In fact there's a good chance that if you were checking the result of performFetch: that it's returning NO and providing you with some sort of error describing the problem.
If you want to fetch the UnsyncedOrderItems that relate to a specific instance of UnsyncedOrders, you need to use a predicate that refers to a specific instance. However, if you already have that instance, you don't need to fetch-- just ask the UnsyncedOrders instance for the value of its items relationship.
This is the solution that I ended up using:
NSManagedObjectContext *context = [[CBICoreDataController sharedInstance] masterManagedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"UnsyncedOrders"
inManagedObjectContext:context];
NSError *error = nil;
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (UnsyncedOrders *info in fetchedObjects) {
[mutableArray addObject:info.items];
}
Is there any way to save chat history to xmpp server permanently.
i.e if i uninstall the application and install it again i am able to restore all the chat from the server?
I am using below code :-
XMPPMessageArchivingCoreDataStorage *_xmppMsgStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
NSManagedObjectContext *moc = [_xmppMsgStorage mainThreadManagedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject"
inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entityDescription];
// [request setFetchLimit:20];
NSError *error;
NSString *predicateFrmt = #"bareJidStr == %#";
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFrmt, userJid];
request.predicate = predicate;
NSArray *messages = [moc executeFetchRequest:request error:&error];
But in this case if i uninstall the application the messages get deleted.
I save to core data and load all messages with code below, but how can I load only messages for 2 users, for self user and for destination user, I want base it on user JID.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context = [[self appDelegate].xmppMessageArchivingCoreDataStorage mainThreadManagedObjectContext];
NSEntityDescription *messageEntity = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject" inManagedObjectContext:context];
fetchRequest.entity = messageEntity;
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"timestamp" ascending:YES];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:fetchRequest error:&error];
//Now you get the NSArray with element type of "XMPPMessageArchiving_Message_CoreDataObject"
assuming your message objects have a from relationshit to a User entity.
As simple as adding (before executing the request):
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"from = %# OR from = %#",selfUser,otherUser];
Where selfUser and otherUser are User core data managed objects or managed object IDs of users.
if you use a field identifier (highly not recomended):
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"bareJID.bare = %# OR bareJID.bare = %#",selfUser.jid,otherUser.jid];
You might want to read THIS
I have used following method and it worked correctly :)
-(void)checkForPastMessageAndDisplayIt
{
NSString *strmyid = #"user1#domain";
NSString *strBuddy = #"user2#domain";
NSManagedObjectContext *moc = [[self appDelegate] managedObjectContext_message_achiving];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject"
inManagedObjectContext:moc];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"bareJidStr = %# OR bareJidStr = %#", strmyid, strBuddy];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *messagesArray = [moc executeFetchRequest:fetchRequest error:&error];
[messagesArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
id messageObject = [messagesArray objectAtIndex:idx];
if ([messageObject isKindOfClass:[XMPPMessageArchiving_Message_CoreDataObject class]]) {
XMPPMessageArchiving_Message_CoreDataObject *currentMessageCoreDataObject = (XMPPMessageArchiving_Message_CoreDataObject*)messageObject;
XMPPMessage *message = currentMessageCoreDataObject.message;
if (message!=nil) {
[messages addObject:message];
}
}
}];
}
You can use like that
-(void)testMessageArchiving {
NSString *strmyid = #"myid";
NSString *strBuddy ="toid";
NSLog(#"my id and buddy is is %# and %#",strmyid,strBuddy);
XMPPMessageArchivingCoreDataStorage *storage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
NSManagedObjectContext *moc = [storage mainThreadManagedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject"
inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
request.predicate = [NSPredicate predicateWithFormat:#"bareJidStr = %# OR bareJidStr = %#", strmyid, strBuddy];
NSError *error;
NSArray *messages = [moc executeFetchRequest:request error:&error];
// NSLog(#"the history of messages is %#",messages);
[self print:[[NSMutableArray alloc]initWithArray:messages]];
I have an NSPredicate which checks the relationship of an entity called "Eval(whosEval)" and if the relationship whosEval matches the full name of another entity, "Athlete(evals)", with the athlete that was selected, it displays all the Evals for that particular Athlete. Unfortunately, my predicate is doing weird things. If I have no athletes, and then add one, then add an eval, it shows all their evals, then I add another, the second athlete won't display any evals I added for that athlete and instead displays all of the other athlete's evals. Am I doing something incorrectly? All evals view controller is displayed prior to add Eval view controller.
allEvals.m
-(void)viewWillAppear:(BOOL)animated{
self.title = [NSString stringWithFormat:#"%#'s Evaluations",_athletesFullName];
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 == %#", _athletesFullName];
[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
}
[self setEvalArray:mutableFetchResults];
[self.tableView reloadData];
}
addEval.m
-(void)saveEval{
//insert saving attributes here
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
_managedObjectContext = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Athlete" inManagedObjectContext:_managedObjectContext]];
NSError *error = nil;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"full == %#", _whichAthletesEval];
[request setPredicate:predicate];
NSArray *results = [_managedObjectContext executeFetchRequest:request error:&error];
Athlete *currentAthlete = [results objectAtIndex:0];
[eval setWhosEval:currentAthlete];
NSLog(#"This Eval Belongs to: %#",eval.whosEval);
NSLog(#"whichAthletesEval value is equal to: %#", _whichAthletesEval);
}
NSError *error = nil;
if(![_managedObjectContext save:&error]){
//handle dat error
}
[self.navigationController popViewControllerAnimated:YES];
}
I have left inline comments (signed off with my initials) in your viewWillAppear: method that point out what I believe to be errors. Essentially, you fetch an arbitrary athlete instead of the one that's been selected (which I'm assuming is the source of _athletesFullName. As far as your saveEval method, your naming conventions are tough to follow so it's not clear to me what further issues you could have here.
-(void)viewWillAppear:(BOOL)animated{
self.title = [NSString stringWithFormat:#"%#'s Evaluations",_athletesFullName];
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;
// No predicate is used at all for the contents of results here - see below - CV
NSArray *results = [_managedObjectContext executeFetchRequest:athleteRequest error:&athleteError];
NSPredicate *athletePredicate = [NSPredicate predicateWithFormat:#"full == %#", _athletesFullName];
// This predicate never used as another predicate is set a few lines below - CV
[request setPredicate:athletePredicate];
// currentAthlete will not necessarily be the one conforming to athletePredicate
// just the first in the array of every Athlete you've fetched - CV
Athlete *currentAthlete = [results objectAtIndex:0];
// because currentAthlete is arbitrary, you're now creating a predicate you likely didn't intend to - CV
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
}
[self setEvalArray:mutableFetchResults];
[self.tableView reloadData];
}