Get openfire Chat History - ios

I am unable to get the history from open fire. I am using XMPP Framework
How to get chat history from open fire archive and print the history data in nslog?

You need to enable the option in openfire to get chat history.
Login on openfire, Go to group chat, then go to group chat settings, then go to history settings and then select show entire chat history option.

On Join xmpp group you have to write below code for store message in xmpp core database.
storage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
moc = [storage mainThreadManagedObjectContext];
XMPPMessageArchiving *xmppMessageArchivingModule = [[XMPPMessageArchiving alloc] initWithMessageArchivingStorage:storage];
[xmppMessageArchivingModule setClientSideMessageArchivingOnly:YES];
[xmppMessageArchivingModule activate:xmppStream];
[xmppMessageArchivingModule addDelegate:self delegateQueue:dispatch_get_main_queue()];
after this when you enter in particular group you have to get history from xmpp core database 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];
NSError *error;
NSString *predicateFrmt = #"bareJidStr == %#";
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFrmt, [NSString stringWithFormat:#"%#%#",GroupName,GROUP_CHAT_DOMAIN]];
request.predicate = predicate;
NSArray *messages = [moc executeFetchRequest:request error:&error];

Related

Deleting a record from coredata with a where clause

I have an entity(UserDetails) which has two columns (username,password).
for eg:
from this I'm populating distinct values and displaying them on a table view.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"UserDetails"
inManagedObjectContext:managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setResultType:NSDictionaryResultType];
[request setReturnsDistinctResults:YES];
[request setPropertiesToFetch:#[#"username",#"password"]];
//not sure if this will generate the same output as what I'm thinking of.
self.users = [[managedObjectContext executeFetchRequest:request error:nil] mutableCopy];
[self.tableView reloadData];
Output expected(from the above code):
(abc,def)
(abc,xyz)
(abc123,def123)
(s01,s01)
Now I want to add a delete feature to the table view which should delete from both table and the core data record.
As they are not populated in the same order as that of the coredata model, I want to delete it using something like a where clause. So whenever I delete (abc,def) it should delete all the similar records in coredata.
can someone help on how to solve this?
TIA
You can do like this:
+(BOOL)deleteDataFromUserDetailsTableWithUserName:(NSString*)strUsername AndPassword :(NSString*)strPassword;
{
AppDelegate *objApDel = (AppDelegate *)[[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [objApDel managedObjectContext];
NSEntityDescription *userEntity=[NSEntityDescription entityForName:kTableName inManagedObjectContext:context];
NSFetchRequest *fetch=[[NSFetchRequest alloc] init];
[fetch setEntity:userEntity];
NSPredicate *p=[NSPredicate predicateWithFormat:#"username == %# AND password=%#", strUsername,strPassword];
[fetch setPredicate:p];
//... add sorts if you want them
NSError *fetchError;
NSArray *fetchedDetails=[context executeFetchRequest:fetch error:&fetchError];
for (self.users *details in fetchedProducts) {
[context deleteObject:details];
}
if (fetchError == nil) {
return YES;
}
else
{
return NO;
}
}
With iOS 9 NSBatchDeleteRequest is available. You can use it to delete objects from CoreData similar to DELETE in SQL using a WHERE clause.
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:#"UserDetails"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"username==%# AND password=%#", #"abc", #"def"];
[request setPredicate:predicate];
NSBatchDeleteRequest *deleteRequest = [[NSBatchDeleteRequest alloc] initWithFetchRequest:request];
NSError *error = nil;
[myPersistentStoreCoordinator deleteRequest withContext:myContext error:&error];
For prior versions you will have to fetch all objects first and then delete them individually. There is no other way.
Also if you are using NSFetchedResultsController you can be notified when those objects get deleted and thus remove them from your UITableView.

store chat history in xmpp server in ios application

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.

How to get chat history of a selected user in XMPP

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

Saving XMPPMessage in CoreData in XMPPFrameWork ios

I am working on a chat application and using xmppframework .Now there is a need for storing message in a persistent storage. Can anyone tell me how can i store and retrieve message from CoreData in IOS.
Since you're using github/robbiehanson/XMPPFramework, it's easy to get both your incoming and outgoing message stored during initializing:
//this code init your XMPPStream
xmppStream = [[XMPPStream alloc]init];
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
xmppStream.autoStartTLS = YES;
xmppReconnect = [[XMPPReconnect alloc]init];
[xmppReconnect activate:self.xmppStream];
xmppMessageArchivingCoreDataStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
xmppMessageArchivingModule = [[XMPPMessageArchiving alloc]initWithMessageArchivingStorage:xmppMessageArchivingCoreDataStorage];
[xmppMessageArchivingModule setClientSideMessageArchivingOnly:YES];
[xmppMessageArchivingModule activate:xmppStream]; //By this line all your messages are stored in CoreData
[xmppMessageArchivingModule addDelegate:self delegateQueue:dispatch_get_main_queue()];
To retrieve the saved message, here's the sample code in my project:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context = [self.xmppMessageArchivingCoreDataStorage mainThreadManagedObjectContext];
NSEntityDescription *messageEntity = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Message_CoreDataObject" inManagedObjectContext:context];
fetchRequest.entity = messageEntity;
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"timestamp" ascending:NO];
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"
Are you using https://github.com/robbiehanson/XMPPFramework
If yes then it by defaults implements core data and you just have to make minor changes to get the chat message...

Core Data - update entity in background thread automatically changes NSManagedObject in Main Thread without merging- why?

i´m currently learning Core Data. Core Data is great but i can not explain the behaviour with a second managed object context in a background thread.
I have an entity called TestEntity with 2 attributes (testId and testDescription)
On the main thread i fetch the entity with the testId = 1 and store this managed object into an instance variable.
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:#"TestEntity" inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
NSNumber *testId = [NSNumber numberWithInt:1];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"testId == %#", testId];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *array = [self.managedObjectContext executeFetchRequest:request error:&error];
t1 = [[array objectAtIndex:0] retain];
TestThread *tt = [TestThread new];
NSOperationQueue *queue = [NSOperationQueue new];
[queue addOperation:tt];
[queue waitUntilAllOperationsAreFinished];
NSLog(#"%#", [t1 valueForKey:#"testDescription"]);
Then is start a NSOperation with a NSOperationQueue called TestThread.
In the main method of this TestThread i create a second managed object context, fetch the same entity (testId = 1) like the main thread, change the testDescription property and save the new context without any errors.
tgAppDelegate *delegate = [[NSApplication sharedApplication] delegate];
self.context = [[[NSManagedObjectContext alloc] init] autorelease];
[context setPersistentStoreCoordinator:delegate.persistentStoreCoordinator];
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:#"TestEntity" inManagedObjectContext:self.context];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
// Set example predicate and sort orderings...
NSNumber *testId = [NSNumber numberWithInt:1];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"testId == %#", testId];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *array = [context executeFetchRequest:request error:&error];
TestEntity *t1 = [array objectAtIndex:0];
t1.testDescription = #"abc";
[context save:&error];
if (error) {
// do something
}
The behaviour i can not explain my self is, that the NSLog output after
[queue waitUntilAllOperationsAreFinished];
has the same string value which updated in my background thread.
abc
My understanding of Core Data and Multithreading is that i have to do an explicit merge between contextes.
In my test app there is no merge.
Can anyone explain why this happenes?
By default, a fetch request will return objects as faults so their content is not actually loaded until you access it (you can learn more about faulting under this link).
To see your expected behavior, try logging the original value of t1.testDescription before you start the second thread.
You can also set
self.context.returnObjectsAsFaults = NO;
but this might have a negative impact on the memory footprint of your app.

Resources