I am starting to develop one XMPP ios client using robbiehanson/XMPPFramework I tried to achieve user is tying.. ie Typing indicator. It is working when both the users are using ios client. When I tried to use multiple client ie one user is using iOS client and another user using Spark desktop clien, the typing indicator is not working.
//Send Typing notification
NSXMLElement *message = [NSXMLElement elementWithName:#"message"];
[message addAttributeWithName:#"type" stringValue:#"chat"];
[message addAttributeWithName:#"to" stringValue:self.userprofile.jidStr];
// [message addChild:body];
// chat notifications
XMPPMessage *xmppMessage = [XMPPMessage messageFromElement:message];
[xmppMessage addComposingChatState];
[appDelegate.xmppStream sendElement:xmppMessage];
// For Receive Typing Notification
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
if ([message hasComposingChatState]) {
self.statusLabel.text=#"is typing...";
}
}
The Typing notification is working fine when both users using my iOS client. But when one using ios client and another user using different client, the Typing notification is not working,
Please provide me the best way to achieve this.
Replace following line
[xmppMessage addComposingChatState];
with
[xmppMessage addMarkableChatMarker];
Other code is fine. Try this.
You need to implement xmpp-0022 , in this way messaging apps implements typing, sent, delivered and seen status
http://xmpp.org/extensions/xep-0022.html#sect-idp643808
Related
A part of my app currently lets a user schedule appointments using a UIDatePicker. They press a button and my backend does some work with the date to store the appointment data, then I send a push using the following code:
NSString *objectID = [NSString stringWithFormat:#"user_%lu", (unsigned long)self.salespersonObject.userID];
PFPush *push = [PFPush new];
[push setChannel:[NSString stringWithFormat:#"%#",objectID]];
NSString *message1 = [NSString stringWithFormat:#"%# sent you an appointment request. Visit your profile in the app to confirm", self.currentUser.fullName];
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:
message1, #"alert",
#"Increment", #"badge",#"default",#"sound",
nil];
[push setData: data];
[push sendPushInBackground];
What I'm wondering ... is there any way using the Parse iOS SDK to set a specific time for a push to be delivered? I'd like to also in this method add a push to be sent 1 hour prior to the UIDatePicker date that says something like "Reminder your appointment with x is in 1 hour"
Thanks in advance!
From Parse Doc :
Sending scheduled push notifications is not currently supported by the
iOS or OS X SDKs. Take a look at the REST API, JavaScript SDK or the
Parse.com push console.
The best thing to do IMO is to use Cloud Code, so you can make a trigger (afterSave, afterDelete) or a function that you call from your iOS App.
Since CloudCode use the Javascript SDK you can make something like that:
var tomorrowDate = new Date(...);
var query = new Parse.Query(Parse.Installation);
query.equalTo('user_id', 'user_123');
Parse.Push.send({
where: query,
data: {
alert: "You previously created a reminder for the game today"
},
push_time: tomorrowDate
}, {
success: function() {
// Push was successful
},
error: function(error) {
// Handle error
}
});
Parse Push notification scheduling Guide
You can use parse Background jobs to schedule the push notification.
Here is the link for documentation
There really isn't a whole lot you can do with the iPhone SDK and a closed app.
I would suggest that you assign the push to a channel, sending notifications is often done from the Parse.com push console, the REST API or from Cloud Code, you can also assign background jobs through this medium.
But if you want to stick to objective C as you don't mention any other languages; You can send Local Push Notifications natively but not through the PARSE SDK.
I am getting 503 error while sending msgs. I know the reason for this error, that I am missing the resource with the domain.
i.e abcd#domain/resource
I am using only abcd#domain. Now, I do not know ,how to get the resource? Which class holds the value for resource ?
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
[body setStringValue:messageStr];
NSXMLElement *message = [NSXMLElement elementWithName:#"message"];
[message addAttributeWithName:#"type"stringValue:#"chat"];
[message addAttributeWithName:#"to"stringValue:[NSString stringWithFormat:#"%#",userId]];
I have the user id as : abcd#domain but I am missing the resource , as the correct value for the variable userId is abcd#domain/resource and I have no idea how to get resource value.
Thanks in advance.
If you do not provide any resource, generally a random resource(number) is assigned when you login. Try providing a resource when you login. All xmpp login functions have the option of providing the resource while calling the function. Check up with the declaration of the login function provided in your library.
I am implementing XMPP in my ios app. I am aware of XMPPMessage+XEP_0085 category which has a few simple methods like addActiveChatState, addComposingChatState and a few others. I want to show chat notifications e.g. when user is typing a message or paused. I am using following code to send message:
NSXMLElement *message = [NSXMLElement elementWithName:#"message"];
[message addAttributeWithName:#"type" stringValue:#"chat"];
[message addAttributeWithName:#"to" stringValue:user];
[message addAttributeWithName:#"id" stringValue:messageID];
[message addChild:body];
[message addChild:setting];
// chat notifications
XMPPMessage *xmppMessage = [XMPPMessage messageFromElement:message];
[xmppMessage addActiveChatState];
[xmppMessage addComposingChatState];
[xmppMessage addPausedChatState];
[xmppMessage addInactiveChatState];
[xmppMessage addGoneChatState];
[_appDelegate.xmppStream sendElement:xmppMessage];
In which xmpp delegate I should receive these notifications. I am not receiving chat notifications in
- (XMPPMessage *)xmppStream:(XMPPStream *)sender willReceiveMessage:(XMPPMessage *)message
delegate.
You are right, XMPPMessage+XEP_0085 category just define some simple methods to add chat state info, but also there are methods to check if chat state exists in message. So, you need to write an XMPPModule which will process message in -xmppStream:... didReceiveMessage: (note, you should use didReceiveMessage) and "multicast" events to others if message hasChatState and/or hasComposingChatState, etc. You can see examples of XMPPModule in the implementations of other XMPP extensions, e.g. XMPPPing
#vitalyster is correct to an extent. This is what I have followed to receive typing notifications properly:
After setting up your XMPPMessage, add chatMarkable to the message:
XMPPMessage *xmppMessage = [XMPPMessage messageFromElement:message];
[xmppMessage addMarkableChatMarker];
and then send new xmppMessage object.
When receiving notification, check if message contains hasInactiveChatState or hasComposingChatState and handle the UI part accordingly.
You guys might need to add some checks according to the project requirement and handling the typing notifications.
Problem : How can I get a successful TURN Connection using the iOS XMPPFramework and an OpenFire Server. I want to be able to send and recieve files.
Note : The base of my code is from the following tutorial : http://mobile.tutsplus.com/tutorials/iphone/building-a-jabber-client-for-ios-server-setup/
Update 13th April 2012 : After more research, I think the real relevant code I need to display in this question is this ...
This is where the TURNSocket attempts to connect
XMPPJID *jid = [XMPPJID jidWithString:#"myFriendsUsername#beta.myCompany.co.uk"];
NSLog(#"Attempting TURN connection to %#", jid);
TURNSocket *turnSocket = [[TURNSocket alloc] initWithStream:[self xmppStream] toJID:jid];
[turnSockets addObject:turnSocket];
[turnSocket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
[turnSocket release];
However, when I debug through the code, in TURNSocket I get to a comment which states that "We were unable to find a single proxy server from our list". This is because the Array 'streamhosts' never gets populated. What could be the issue? Is there some XML somewhere that should tell me the problem? Is the issue likely to be with OpenFire?
The problem is caused if a full jID with a resource is not provided to TurnSocket.m! This is passed in in viewDidLoad of SMChatViewController
e.g Use
friendsUsername#beta.myCompany.co.uk/spark
rather than
friendsUsername#beta.myCompany.co.uk
My progress on this project can be followed here
This is the class method of TURNSocket you call to
populate the proxy candidates of the TURNSocket
stream host. So you should put streamhost back to
what it was before stream-host.
+ (void)setProxyCandidates:(NSArray *)candidates;
[TURNSocket setProxyCandidates:#["host1.somedomain.com", #"host2.someotherdomain.com"]];
In processRequestResponse.m in TurnSocket, the name of the streamhost element wasn't what OpenFire was giving me. I have changed it from this
NSXMLElement *streamhostUsed = [query elementForName:#"streamhost-used"];
to this
NSXMLElement *streamhostUsed = [query elementForName:#"streamhost"];
However, I now have a new error which I am starting a new question for ... OpenFire/XMPP 503 service-unavailable error (XEP-0065 using iOS XMPPFramework)
Update 20/4/2012 : I now believe this answer is wrong! If it was working correctly, streamhostUsed would be there, rather than streamhost with an error!
I use the following code found on Facebook developer site to do a wall post:
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"http://developers.facebook.com/docs/reference/dialogs/", #"link",
#"http://fbrell.com/f8.jpg", #"picture",
#"Facebook Dialogs", #"name",
#"Reference Documentation", #"caption",
#"Dialogs provide a simple, consistent interface for apps to interact with users.", #"description", nil];
[_facebook dialog:#"feed" andParams:params andDelegate:self];
This shows a popup letting the user write his message and press publish or cancel.
Is there any way to know if the post has been successfully pusblished or not (cancellation or connection problem)?
Many thanks!
Try using specifying a delegate other than self to be able to capture the response of the dialog.
See: http://developers.facebook.com/docs/reference/iossdk/dialog/
You should call this dialog if the method you are calling requires
parameters to set up the dialog. You should set up your delegate to
handle the scenarios where the dialog succeeds, is cancelled by the
user, as well as any error scenarios.
As for the delegate: http://developers.facebook.com/docs/reference/iossdk/FBRequestDelegate/ I would assume it would be the request:didReceiveResponse: delegate.
EDIT
with additional feedback, your answer lies in the dialogDidComplete delegate listed on the link I gave in my original response.
I think you can do it by using - (void)dialogDidComplete:(FBDialog *)dialog; method of FBDialogDelegate.
+1 for Hlung and DMCS for their help but it looks like the feed dialog is getting more and more deprecated, and handling proper callbacks is fiddly (impossible?).
Plus the FB doc isn't up-to-date.
So I ended up using a (void)requestWithGraphPath instead of (void)dialog which requires an extra permission to post on user's wall but works better with the 2 following callbacks:
- (void)request:(FBRequest *)request didLoad:(id)result
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error
Somewhat related to your question - I was trying to figure out which dialog had completed.
You can detect the parameters of the dialog, and check which one it is. I have this issue, as I send various dialogs, and want to know on the other end which one was a success or not.
- (void)dialogDidComplete:(FBDialog *)dialog {
// the song feed return
NSLog(#"params; %#",dialog.params);
if([[dialog.params objectFOrKey:#"ref"] isEqualtoString:#"songfeed"]){
// do stuff on return from this dialog
}
}