I have gone through the XEP 0184 and have done following implementation.
If XMPP is connected and packet then is send then i set the status for each message as SENT (✔︎) if I don't get following callback.
-(void)xmppStream:(XMPPStream *)sender didReceiveError:(id)error
If i get the received status from XEP 0184 implemented in Objective C, I set the status as Delivered (✔︎✔︎)
RECV: < message xmlns="jabber:client" from="+122232322#wer.com/2323"
to="+3343232322#wer.com/2223" lang="" >< received
xmlns="urn:xmpp:receipts" id="avv-33343"/ >< /message >
But my question is how to show the SEEN status for each message as readh XMPP 0079 that is Advanced Messaging protocol is doing this. But I could not find in Objective C.
Can anyone please help? If my direction is correct and I am missing something could you let me know?
A code snippet guidance would be much appreciated.
Here is my implementation.
Using the stack documentation help I have added the following lines to get the delivery receipts.
XMPPMessageDeliveryReceipts* xmppMessageDeliveryReceipts = [[XMPPMessageDeliveryReceipts alloc] initWithDispatchQueue:dispatch_get_main_queue()];
xmppMessageDeliveryReceipts.autoSendMessageDeliveryReceipts = YES;
xmppMessageDeliveryReceipts.autoSendMessageDeliveryRequests = YES;
[xmppMessageDeliveryReceipts activate:self.xmppStream];
Now due to this I get the following response for the send and RECV xml.
SEND: 111111111 for avv-33343 Id message.
RECV: < message xmlns="jabber:client" from="+122232322#wer.com/2323"
to="+3343232322#wer.com/2223" lang="" >< received
xmlns="urn:xmpp:receipts" id="avv-33343"/ >< /message >
But this is just giving me info that the message is delivered but how to send the SEEN receipts like above to intimate the sender that the other end user have acknowledged + SEEN the message.
Something like this ... RECV: < seen xmlns="urn:xmpp:receipts" id="222-4444"/ >
For seen status use same functionality as send a normal message with same id which message received and you want to mark seen on Sender device,
When on sender device receive a static message #"to#fromSeen" with same message id for sent/delivered message, When receiver get exist msg id already in db then your purpose resolve .
Code for send seen status
NSString *bodymessageString = [NSString stringWithFormat:#"to#fromSeen"];
NSString *str_loginUser = [NSString stringWithFormat:#"%##%#", [[NSUserDefaults standardUserDefaults]valueForKey:#"mobile"],kXMPPServer ];
NSString *str_OtherUser = [NSString stringWithFormat:#"%##%#",str_OtherUserRegName,kXMPPServer];
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
[body setStringValue:bodymessageString];
NSXMLElement *message = [NSXMLElement elementWithName:#"message"];
[message addAttributeWithName:#"type" stringValue:#"chat"];
[message addAttributeWithName:#"from" stringValue:str_loginUser];
// [[[delegate xmppStream] myJID] bare]
[message addAttributeWithName:#"to" stringValue:str_OtherUser];
// NSString *messageID= [XMPPStream generateUUID];
[message addAttributeWithName:#"id" stringValue:str_msgID];
// NSXMLElement *request = [NSXMLElement elementWithName:#"request" xmlns:#"urn:xmpp:receipts"];
// [message addChild:request];
[message addChild:body];
[[delegate xmppStream] sendElement:message];
[ChatData GetUpdateToDatabase:str_msgID :#"Seen"];
Code for check message status in appdelegate file
if ([message isChatMessageWithBody])
{
if ([msg isEqualToString:#"to#fromSeen"])
{
BOOL is_Exist;
is_Exist = [ChatData GetAllReadyAvailable :message.elementID];
if (is_Exist == YES)
{
NSString *str_status = [ChatData getstatusChatBy:message.elementID];
if (![str_status isEqualToString:#"Seen"])
{
[ChatData GetUpdateToDatabase:message.elementID :#"Seen"];
}
}
}
else
{
BOOL is_Exist;
is_Exist = [ChatData GetAllReadyAvailable :message.elementID];
if (is_Exist == NO)
{
// Store message in DB
}
}
}
else if ([message hasReceiptResponse])
{
}
else if([message isErrorMessage])
{}
Related
HI I am developing chat app so i am using xmpp framework.Chatting is working fine but how to get the message delivery like in whatsapp, facebook etc.,i searched for that i found some document here is my code upto now i am implemented
in connect Method
XMPPMessageDeliveryReceipts* xmppMessageDeliveryRecipts = [[XMPPMessageDeliveryReceipts alloc] initWithDispatchQueue:dispatch_get_main_queue()];
xmppMessageDeliveryRecipts.autoSendMessageDeliveryReceipts = YES;
xmppMessageDeliveryRecipts.autoSendMessageDeliveryRequests = YES;
[xmppMessageDeliveryRecipts activate:self.xmppStream];
added this lines in sending messsage method
NSXMLElement *request = [NSXMLElement elementWithName:#"request"];
[request addAttributeWithName:#"xmlns" stringValue:#"urn:xmpp:receipts"];
[message addChild:request];
[message addChild:body];
but This is for message delivered or not how can we check the deliverd message read or not i have seen these extentions XEP-0184,XEP-0333 but I don't have any idea to implement the read /unread messages. please help me
If you want to get the read receipts then instead of sending auto message delivery receipts, send it whenever user reads that message. Each message has it's corresponding message_id. Use that message_id to send the delivery receipt for the particular message that has been read. So, comment the following line
//xmppMessageDeliveryRecipts.autoSendMessageDeliveryReceipts = YES;
I solved this problem by adding 'chatStatus' attribute in my message entity. For sender I have kept value of chatStatus as sent, unsent, or received(received by other side or not). For Receiver Side I have kept the Values as read or unread(Have I read message or not, So that for unread message I could send read Receipts).
On Click Of send Button:
//Save to your Message Entity
NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
[m setObject: message_body forKey:#"message_body"];
[m setObject:messageID forKey:#"message_id"];
[m setObject:#"yes" forKey:#"isOutgoing"];
[m setObject:dateString forKey:#"date"];
[m setObject:timeString forKey:#"time"];
[m setObject:[NSDate date] forKey:#"timeStamp"];
[m setObject:yourId forKey:#"from"];
[m setObject:toId forKey:#"to"];
if (!Is_InternetAvailable]) {
[m setObject:unsent forKey:#"chatStatus"];
}
else{
[m setObject:sent forKey:#"chatStatus"];
}
[[CoreDataMethods sharedCoreDataMethods] saveUserMessage:m];
}
In cellForRowAtIndexPath:
if ([message isoutGoing]) {//If I have sent the message
// Mine bubble
if ([[messageDict valueForKey:#"chatStatus"] isEqualToString:unsent]) {
//set unsent image
}
else if ([[messageDict valueForKey:#"chatStatus"] isEqualToString:sent]){
//set sent image
}
else if ([[messageDict valueForKey:#"chatStatus"] isEqualToString:received]){
//set Received Image
}
}
else{
// Other Bubble , Notify them that you have read the message if it is unread/new message
if ([[messageDict valueForKey:#"chatStatus"] isEqualToString:unread]) {
//send read receipt
NSXMLElement *receivedelement = [NSXMLElement elementWithName:#"received" xmlns:#"urn:xmpp:receipts"];
NSXMLElement *message = [NSXMLElement elementWithName:#"message" xmlns:#"jabber:client"];
[message addAttributeWithName:#"to" stringValue:toId];
[message addAttributeWithName:#"from" stringValue:fromID];
[receivedelement addAttributeWithName:#"id" stringValue:[messageDict valueForKey:#"message_id"]];
[message addChild:receivedelement];
//XMPPMessage *generatedReceiptResponse = [[messageDict valueForKey:#"xmppMessage"] generateReceiptResponse];
[[[kAppDelegate xmppHandler] xmppStream] sendElement:message];
// update message entity
[self updateChatStatus:read withMessageID:[messageDict valueForKey:#"message_id"]];
}
}
And finally when you receive the delivery Receipt in didReceiveMessage, update the chatStatus to received
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message{
if ([message hasReceiptResponse]) {//message read
//Update database message entity
[self updateChatStatus:#"received" withMessageID:[message receiptResponseID]];
}
}
You could set the values of chatStatus as per your requirement. As for unsent messages I have set it as sent in didSendMessage delegate.
Hope it Helps!!
I am able to send messages to users which means i have a working and authenticated xmppStream.
But i am unable to send and receive acknowledgement from server. I want to know which message was received successfully by the server. I googled and found that XEP-0198 should be implemented for this. I am using ejabberd as XMPP server and it supports XEP-0198.
I tried that but i don't know if i am doing it right or not.
First of all i included the header file and added XMPPStreamManagementDelegate.
#import "XMPPStreamManagement.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate,XMPPStreamManagementDelegate>
In the implementation file, here's how i have defined the stream.
XMPPStream *xmppS = [[XMPPStream alloc] init];
[xmppS addDelegate:self delegateQueue:dispatch_get_main_queue()];
XMPPStreamManagement *xsm = [[XMPPStreamManagement alloc] init];
[xsm addDelegate:self delegateQueue:dispatch_get_main_queue()];
[xsm activate:xmppS];
After that i connect with the server. After the connection is successful, i send an enable stanza.
NSXMLElement *enable = [NSXMLElement elementWithName:#"enable" xmlns:#"urn:xmpp:sm:3"];
[xsm.xmppStream sendElement:enable];
Then i send a message
NSXMLElement *a = [NSXMLElement elementWithName:#"request" xmlns:#"urn:xmpp:receipts"];
XMPPElement *e = [[XMPPElement alloc] initWithName:#"message"];
[e addAttributeWithName:#"id" stringValue:#"123456"];
[e addAttributeWithName:#"type" stringValue:#"chat"];
[e addAttributeWithName:#"to" stringValue:#"testuser#myxmppserver.com"];
[e addAttributeWithName:#"from" stringValue:#"testuser2#myxmppserver.com"];
[e addChild:a];
[xsm.xmppStream sendElement:e];
Test User receives the message and Test User 2 gets the received stanza.
<received xmlns="urn:xmpp:receipts" id="123456"/>
My problem is if i send the following stanza, i receive no message.
NSXMLElement *r = [NSXMLElement elementWithName:#"r"];
[xsm.xmppStream sendElement:r];
I have implemented the following function
-(void)xmppStreamManagementDidRequestAck:(XMPPStreamManagement *)sender
{
NSLog(#"ACK");
}
But still nothing gets printed.
Please help. Also, how can i know when the server has received the sent message.
Let me know if anyone wants to know any other part of code from my side.
You can use the functions in xmppStreamManagement for sending the request and get received id:
[xmppStreamManagement requestAck];
and
- (void)xmppStreamManagement:(XMPPStreamManagement *)sender wasEnabled:(NSXMLElement *)enabled
- (void)xmppStreamManagement:(XMPPStreamManagement *)sender didReceiveAckForStanzaIds:(NSArray *)stanzaIds
make sure the stream management is enabled by:
[self.xmppStreamManagement enableStreamManagementWithResumption:YES maxTimeout:0];
I have made one-to-one chat using XMPP protocol. Now, I would like to send image and video in my application. I researched about the file transfer but I didn't find a solution. I have also used the code below for Socket connection.
Please advice me on how I can go about doing this.
[TURNSocket setProxyCandidates:#[#"MyserverHost-desktop"]];
XMPPJID *jid = [XMPPJID jidWithString:#"1254225445#MyserverHost-desktop"];
TURNSocket *turnSocket = [[TURNSocket alloc] initWithStream:[[self appDelegate]xmppStream] toJID:jid];
[app.turnSocketArray addObject:turnSocket];
[turnSocket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
[turnSocket release];
- (void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket
{
}
- (void)turnSocketDidFail:(TURNSocket *)sender
{
}
Every time connection fail method call..
Thanks.
you need push the image to server and you will reveice a url from server .then you can send the url to another device by xmpp protocol. in the end. download the image from server by the received url.
xmpp also can send image . But that's a big xml message for xmpp server .that's not a great solution.
Try this...
NSData *dataF = UIImagePNGRepresentation(SendImage);
NSString *imgStr=[dataF base64Encoding];
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
[body setStringValue:messageStr];
NSXMLElement *imgAttachement = [NSXMLElement elementWithName:#"attachment"];
[imgAttachement setStringValue:imgStr];
NSXMLElement *message = [NSXMLElement elementWithName:#"message"];
[message addAttributeWithName:#"type" stringValue:#"chat"];
[message addAttributeWithName:#"to" stringValue:chatWithUser];
[message addChild:body];
[message addChild:imgAttachement];
[self.xmppStream sendElement:message];
I hope this will help you...
I am using XMPP in my app. My messages are not being sent whenever I attempt to send a message to any specific ID (for example 'test.codemen#gmail.com' in my code).
My code is given below. Thanks in advance.
- (IBAction)sendMsg:(id)sender
{
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
[body setStringValue:msgField.text];
NSXMLElement *message = [NSXMLElement elementWithName:#"message"];
[message addAttributeWithName:#"type" stringValue:#"chat"];
[message addAttributeWithName:#"to" stringValue:#"test.codemen#gmail.com"];
[message addChild:body];
iPhoneXMPPAppDelegate *share = [iPhoneXMPPAppDelegate sharedInstance];
[[share xmppStream] sendElement:message];
}
your code looks fine to me.
Google Talk routes messages only to contacts you are subscribed to. Is the user you send the message to on your contact list?
Print the xml , then see what's in the message .Maybe you are sending message to a wrong JID .
I am creating a chat application using XMPP Framework in iPhone. I wish to know the process for sending and receiving messages. Can anyone give me a solution for this?
Thanks in advance.
Download XMPPFramework and unzip it. There are several folders inside. Open the 'Xcode' folder > open 'iPhoneXMPP' folder > click on 'iPhoneXMPP.xcodeproj' > run it. It asks login credential first. Upon successful login, it will show your buddy list. It works fine for gmail. There is one call back method which is called for every incoming message:
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
user = [xmppRosterStorage userForJID:[message from] xmppStream:sender managedObjectContext:[self managedObjectContext_roster]];
if ([message isChatMessageWithBody])
{
NSString *body = [[message elementForName:#"body"] stringValue];
NSString *from = [[message attributeForName:#"from"] stringValue];
NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
[m setObject:body forKey:#"msg"];
[m setObject:from forKey:#"sender"];
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
{
NSLog(#"Applications are in active state");
//send the above dictionary where ever you want
}
else
{
NSLog(#"Applications are in Inactive state");
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertAction = #"Ok";
localNotification.applicationIconBadgeNumber=count;
localNotification.alertBody =[NSString stringWithFormat:#"From:"%#\n\n%#",from,body];
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
//send the above dictionary where ever you want
}
}
}
For sending message we have to write our own method where ever you want:
-(void)sendMessage
{
NSString *messageStr =messageField.text;
if([messageStr length] > 0)
{
NSLog(#"Message sending fron Gmail");
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
[body setStringValue:messageStr];
NSXMLElement *message = [NSXMLElement elementWithName:#"message"];
[message addAttributeWithName:#"type" stringValue:#"chat"];
[message addAttributeWithName:#"to" stringValue:#"destination address"];
[message addChild:body];
NSLog(#"message1%#",message);
[[self appDelegate].xmppSream sendElement:message];
}
}
For Sending the message in groups/Room below is the snippet
XMPPMessage *message = [XMPPMessage message];
[message addBody:#"123"];
[self.currentRoom sendMessage:message1];
Where self.currentRoom is XMPPRoom
If you are sending message from Room/Group then use this code for sending messages.
[xmppRoom sendMessage:#"Hi All"];
Don't need to send the messages through xmppStream. This Single line of code works perfectly for me.
Quick google search reveals many XMPP libraries, either C/C++ or ObjC. Perhaps http://code.google.com/p/xmppframework/ would be a good starting point, though I haven't tried it personally.
Here is a solution to send message via XMPPFramework in Swift 3
let user = XMPPJID(string: "user#jabjab.de")
let msg = XMPPMessage(type: "chat", to: user)
msg?.addBody("Message to send")
self.xmppStream.send(msg)