Change XMPPPresence to Away/Busy/Invisible

5.4k views Asked by At

How do you change your presence to show dnd/away and etc.?

XMPPPresence *presence = [XMPPPresence presenceWithType:status];
[[[self appDelegate] xmppStream] sendElement:presence];

status is an NSString that I set to online/unavailable/away/busy/invisible.

It only works when I go online and/or unavailable.

Here's how it looks like after sending presence in my xmppStream:

<presence type="away"><x xmlns="vcard-temp:x:update"><photo/></x></presence>
3

There are 3 answers

1
Bashar Altakrouri On BEST ANSWER

To change the status of your client you will need to use this simple code:

XMPPPresence *presence = [XMPPPresence presence];
NSXMLElement *status = [NSXMLElement elementWithName:@"status"];
[status setStringValue:@"online/unavailable/away/busy/invisible"];
[presence addChild:status];
[[self xmppStream] sendElement:presence];

This simply means that the key to change the status of your client is by adding a status element to your presence. Please note that the openfire server will only show the "available/Offline" status when you hover on the user icon in the admin panel. This should not confuse you though. You can simply check the presence message sent by your client and received by the others which will show on of the status you have set ("online/unavailable/away/busy/invisible").

0
eyup cimen On

For Swift 5 and above

You can send to status any user

let presence = XMPPPresence(show: XMPPPresence.ShowType(rawValue: XMPPPresence.ShowType.away.rawValue) , status: "I'm working")

stream.send(presence)

and You can listen to all status with above methods

class LastStatus {
    var username :String
    var lastStatus : String
    
    internal init(username: String, lastStatus: String) {
        self.username = username
        self.lastStatus = lastStatus
    }
}

var lastStatusList : [LastStatus] = []
func xmppStream(_ sender: XMPPStream, didReceive presence: XMPPPresence) {
    
    guard let fromUser = presenceFrom.user else {return}
    
    if presence.showType == XMPPPresence.ShowType.init(rawValue: "away") {
        if let status = presence.status {
            
            if lastStatusList.firstIndex(where: { $0.username == fromUser}) == nil {
                let userStatus = LastStatus(username: fromUser , lastStatus: status)
                lastStatusList.append(userStatus)
            } else {
                let index = lastStatusList.firstIndex(where: { $0.username == fromUser})!
                let changing = lastStatusList[index]
                changing.lastStatus = status
            }
            
        }
    }
}
2
Keith OYS On

On top of the answer above, there is also a <show> element that should be used in conjunction with the <status> element. By using both elements, you can customize user's presence for each availability states.

Default: Available / Offline

By using <show>: Available / Busy / Away / Extended Away / Offline

By using <show> with <status>: "Free to chat" / "Hard at work" / "In a meeting" / "Out for lunch".


If you use Openfire with this method: In User Sessions > Presence column, you will see:

  1. Different colored icons for each user (e.g. green for available, red for busy, etc.)

  2. A descriptive text beside the icons (e.g. "In a meeting")


Presence child elements

There are 3 elements that can change types of presence in XMPP.

  1. <show/>
  2. <status/>
  3. <priority/> (we'll exclude this for discussion)

Show

<show> specifies an availability status of a user.

Values of the element must be specified according to the list below.

"chat" -- user is actively interested in chatting.
"dnd"  -- user is busy (dnd a.k.a 'Do Not Disturb').
"away" -- user is temporarily away.
"xa"   -- user is away for an extended period (xa a.k.a. 'eXtended Away').

If this element is not provided, user is assumed to only be either online and available.

Status

<status> describes the availability status of a user. It is usually used in conjunction with the <show> element to provide a detailed description of an availability state.

Values of the element can be of any descriptive text. For instance:

"Available to chat" -- can be used for "chat"
"Busy at work"      -- can be used for "dnd"
"In a meeting"      -- can be used for "away"
"On a vacation"     -- can be used for "xa"

Usage in Objective-C

Here's how you should apply the above concept in code.

// Initialize variables
XMPPPresence *presence = [XMPPPresence presence];
NSXMLElement *show = [NSXMLElement elementWithName:@"show"];
NSXMLElement *status = [NSXMLElement elementWithName:@"status"];

// If user is available
[show setStringValue:@"chat"];
[status setStringValue:@"Available to chat"];

// If user is busy
[show setStringValue:@"dnd"];
[status setStringValue:@"Busy at work"];

// If user is away
[show setStringValue:@"away"];
[status setStringValue:@"In a meeting"];

// If user is away for a long period of time
[show setStringValue:@"xa"];
[status setStringValue:@"On a vacation"];

// Add the XML child elements to XMPPPresence
[presence addChild:show];
[presence addChild:status];

// Update new presence to server
[[[self appDelegate] xmppStream] sendElement:presence];

There you go, your customized user's presence will now be accurately reflected in your server.

See also: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence