5. Usage examples

5.1. Simple client sending message

Below is example code of client which send XMPP message to recipient@domain.com as sender@domain.com using Pa$$w0rd as password for authentication. Message is sent just after clients connects to server, authenticates and establishes session.

import Foundation
import TigaseSwift

class MessageSendingClient: EventHandler {

    var client: XMPPClient;

    init() {
        Log.initialize();

        client = XMPPClient();

        registerModules();

        print("Notifying event bus that we are interested in SessionEstablishmentSuccessEvent" +
            " which is fired after client is connected");
        client.eventBus.register(handler: self, for: SessionEstablishmentModule.SessionEstablishmentSuccessEvent.TYPE);
        print("Notifying event bus that we are interested in DisconnectedEvent" +
            " which is fired after client is connected");
        client.eventBus.register(handler: self, for: SocketConnector.DisconnectedEvent.TYPE);

        setCredentials(userJID: "[email protected]", password: "Pa$$w0rd");

        print("Connecting to server..")
        client.login();
        print("Started async processing..");
    }

    func registerModules() {
        print("Registering modules required for authentication and session establishment");
        _ = client.modulesManager.register(AuthModule());
        _ = client.modulesManager.register(StreamFeaturesModule());
        _ = client.modulesManager.register(SaslModule());
        _ = client.modulesManager.register(ResourceBinderModule());
        _ = client.modulesManager.register(SessionEstablishmentModule());

        print("Registering module for sending/receiving messages..");
        _ = client.modulesManager.register(MessageModule());
    }

    func setCredentials(userJID: String, password: String) {
        let jid = BareJID(userJID);
        client.connectionConfiguration.setUserJID(jid);
        client.connectionConfiguration.setUserPassword(password);
    }

    /// Processing received events
    func handle(event: Event) {
        switch (event) {
        case is SessionEstablishmentModule.SessionEstablishmentSuccessEvent:
            sessionEstablished();
        case is SocketConnector.DisconnectedEvent:
            print("Client is disconnected.");
        default:
            print("unsupported event", event);
        }
    }

    /// Called when session is established
    func sessionEstablished() {
        print("Now we are connected to server and session is ready..");

        let messageModule: MessageModule = client.modulesManager.getModule(MessageModule.ID)!;
        let recipient = JID("[email protected]");
        let chat = messageModule.createChat(with: recipient);
        print("Sending message to", recipient, "..");
        _ = messageModule.sendMessage(in: chat!, body: "I'm now online..");

        print("Waiting 1 sec to ensure message is sent");
        sleep(1);
        print("Disconnecting from server..");
        client.disconnect();
    }
}

5.2. Simple client setting presence and handling incoming presences

In this example we will connect to server, set our presence to Do not disturb with status message set to Do not disturb me!.

This example will also print any presence we will receive from our contacts. However for this part to work our roster cannot be empty and at least one of our roster contacts needs to be available.

import Foundation
import TigaseSwift

class PresenceHandlingClient: EventHandler {

    var client: XMPPClient;

    init() {
        Log.initialize();

        client = XMPPClient();

        registerModules();

        print("Notifying event bus that we are interested in SessionEstablishmentSuccessEvent" +
            " which is fired after client is connected");
        client.eventBus.register(handler: self, for: SessionEstablishmentModule.SessionEstablishmentSuccessEvent.TYPE);
        print("Notifying event bus that we are interested in DisconnectedEvent" +
            " which is fired after client is connected");
        client.eventBus.register(handler: self, for: SocketConnector.DisconnectedEvent.TYPE);
        print("Notifying event bus that we are interested in ContactPresenceChangedEvent");
        client.eventBus.register(handler: self, for: PresenceModule.ContactPresenceChanged.TYPE);

        setCredentials(userJID: "[email protected]", password: "Pa$$w0rd");

        print("Connecting to server..")
        client.login();
        print("Started async processing..");
    }

    func registerModules() {
        print("Registering modules required for authentication and session establishment");
        _ = client.modulesManager.register(AuthModule());
        _ = client.modulesManager.register(StreamFeaturesModule());
        _ = client.modulesManager.register(SaslModule());
        _ = client.modulesManager.register(ResourceBinderModule());
        _ = client.modulesManager.register(SessionEstablishmentModule());

        print("Registering module for handling presences..");
        _ = client.modulesManager.register(PresenceModule());
    }

    func setCredentials(userJID: String, password: String) {
        let jid = BareJID(userJID);
        client.connectionConfiguration.setUserJID(jid);
        client.connectionConfiguration.setUserPassword(password);
    }

    /// Processing received events
    func handle(event: Event) {
        switch (event) {
        case is SessionEstablishmentModule.SessionEstablishmentSuccessEvent:
            sessionEstablished();
        case is SocketConnector.DisconnectedEvent:
            print("Client is disconnected.");
        case let cpc as PresenceModule.ContactPresenceChanged:
            contactPresenceChanged(cpc);
        default:
            print("unsupported event", event);
        }
    }

    /// Called when session is established
    func sessionEstablished() {
        print("Now we are connected to server and session is ready..");

        let presenceModule: PresenceModule = client.modulesManager.getModule(PresenceModule.ID)!;
        print("Setting presence to DND...");
        presenceModule.setPresence(show: Presence.Show.dnd, status: "Do not distrub me!", priority: 2);
    }

    func contactPresenceChanged(_ cpc: PresenceModule.ContactPresenceChanged) {
        print("We got notified that", cpc.presence.from, "changed presence to", cpc.presence.show);
    }
}

5.3. Simple client setting presence, handling incoming presences and responding on incoming messages

This example presents way to listen for incoming messages and responding on this messages.

import Foundation
import TigaseSwift

class MessageRespondingClient: EventHandler {

    var client: XMPPClient;

    init() {
        Log.initialize();

        client = XMPPClient();

        registerModules();

        print("Notifying event bus that we are interested in SessionEstablishmentSuccessEvent" +
            " which is fired after client is connected");
        client.eventBus.register(handler: self, for: SessionEstablishmentModule.SessionEstablishmentSuccessEvent.TYPE);
        print("Notifying event bus that we are interested in DisconnectedEvent" +
            " which is fired after client is connected");
        client.eventBus.register(handler: self, for: SocketConnector.DisconnectedEvent.TYPE);
        print("Notifying event bus that we are interested in ContactPresenceChangedEvent and in MessageReceivedEvent");
        client.eventBus.register(handler: self, for: PresenceModule.ContactPresenceChanged.TYPE, MessageModule.MessageReceivedEvent.TYPE);

        setCredentials(userJID: "[email protected]", password: "Pa$$w0rd");

        print("Connecting to server..")
        client.login();
        print("Started async processing..");
    }

    func registerModules() {
        print("Registering modules required for authentication and session establishment");
        _ = client.modulesManager.register(AuthModule());
        _ = client.modulesManager.register(StreamFeaturesModule());
        _ = client.modulesManager.register(SaslModule());
        _ = client.modulesManager.register(ResourceBinderModule());
        _ = client.modulesManager.register(SessionEstablishmentModule());

        print("Registering module for handling presences..");
        _ = client.modulesManager.register(PresenceModule());
        print("Registering module for handling messages..");
        _ = client.modulesManager.register(MessageModule());
    }

    func setCredentials(userJID: String, password: String) {
        let jid = BareJID(userJID);
        client.connectionConfiguration.setUserJID(jid);
        client.connectionConfiguration.setUserPassword(password);
    }

    /// Processing received events
    func handle(event: Event) {
        switch (event) {
        case is SessionEstablishmentModule.SessionEstablishmentSuccessEvent:
            sessionEstablished();
        case is SocketConnector.DisconnectedEvent:
            print("Client is disconnected.");
        case let cpc as PresenceModule.ContactPresenceChanged:
            contactPresenceChanged(cpc);
        case let mr as MessageModule.MessageReceivedEvent:
            messageReceived(mr);
        default:
            print("unsupported event", event);
        }
    }

    /// Called when session is established
    func sessionEstablished() {
        print("Now we are connected to server and session is ready..");

        let presenceModule: PresenceModule = client.modulesManager.getModule(PresenceModule.ID)!;
        print("Setting presence to DND...");
        presenceModule.setPresence(show: Presence.Show.dnd, status: "Do not distrub me!", priority: 2);
    }

    func contactPresenceChanged(_ cpc: PresenceModule.ContactPresenceChanged) {
        print("We got notified that", cpc.presence.from, "changed presence to", cpc.presence.show);
    }

    func messageReceived(_ mr: MessageModule.MessageReceivedEvent) {
        print("Received new message from", mr.message.from, "with text", mr.message.body);

        let messageModule: MessageModule = client.modulesManager.getModule(MessageModule.ID)!;
        print("Creating chat instance if it was not received..");
        let chat = mr.chat ?? messageModule.createChat(with: mr.message.from!);
        print("Sending response..");
        _ = messageModule.sendMessage(in: chat!, body: "Message in response to: " + (mr.message.body ?? ""));
    }
}

5.4. Simple client with support for MUC

In this example you can find how to join to room, send message to room and handle informations about occupants.

import Foundation
import TigaseSwift

class MucClient: EventHandler {

    var client: XMPPClient;

    init() {
        Log.initialize();

        client = XMPPClient();

        registerModules();

        print("Notifying event bus that we are interested in SessionEstablishmentSuccessEvent" +
            " which is fired after client is connected");
        client.eventBus.register(handler: self, for: SessionEstablishmentModule.SessionEstablishmentSuccessEvent.TYPE);
        print("Notifying event bus that we are interested in DisconnectedEvent" +
            " which is fired after client is connected");
        client.eventBus.register(handler: self, for: SocketConnector.DisconnectedEvent.TYPE);

        print("Notifying event but that we are interested in some of MucModule events");
        client.eventBus.register(handler: self, for: MucModule.YouJoinedEvent.TYPE, MucModule.MessageReceivedEvent.TYPE, MucModule.OccupantComesEvent.TYPE, MucModule.OccupantLeavedEvent.TYPE, MucModule.OccupantChangedPresenceEvent.TYPE);

        setCredentials(userJID: "[email protected]", password: "Pa$$w0rd");

        print("Connecting to server..")
        client.login();
        print("Started async processing..");
    }

    func registerModules() {
        print("Registering modules required for authentication and session establishment");
        _ = client.modulesManager.register(AuthModule());
        _ = client.modulesManager.register(StreamFeaturesModule());
        _ = client.modulesManager.register(SaslModule());
        _ = client.modulesManager.register(ResourceBinderModule());
        _ = client.modulesManager.register(SessionEstablishmentModule());

        print("Registering module for handling presences..");
        _ = client.modulesManager.register(PresenceModule());
        print("Registering module for handling messages..");
        _ = client.modulesManager.register(MessageModule());
        print("Registering module for handling MUC...");
        _ = client.modulesManager.register(MucModule());
    }

    func setCredentials(userJID: String, password: String) {
        let jid = BareJID(userJID);
        client.connectionConfiguration.setUserJID(jid);
        client.connectionConfiguration.setUserPassword(password);
    }

    /// Processing received events
    func handle(event: Event) {
        switch (event) {
        case is SessionEstablishmentModule.SessionEstablishmentSuccessEvent:
            sessionEstablished();
        case is SocketConnector.DisconnectedEvent:
            print("Client is disconnected.");
        case let cpc as PresenceModule.ContactPresenceChanged:
            contactPresenceChanged(cpc);
        case let mr as MessageModule.MessageReceivedEvent:
            messageReceived(mr);
        case let mrj as MucModule.YouJoinedEvent:
            mucRoomJoined(mrj);
        case let mmr as MucModule.MessageReceivedEvent:
            mucMessageReceived(mmr);
        case let mro as MucModule.OccupantComesEvent:
            print("Occupant", mro.occupant.nickname, "entered room with presence", mro.presence);
        case let mro as MucModule.OccupantLeavedEvent:
            print("Occupant", mro.occupant.nickname, "left room");
        case let mro as MucModule.OccupantChangedPresenceEvent:
            print("Occupant", mro.occupant.nickname, "changed presence to", mro.presence)
        default:
            print("unsupported event", event);
        }
    }

    /// Called when session is established
    func sessionEstablished() {
        print("Now we are connected to server and session is ready..");

        let presenceModule: PresenceModule = client.modulesManager.getModule(PresenceModule.ID)!;
        print("Setting presence to DND...");
        presenceModule.setPresence(show: Presence.Show.dnd, status: "Do not distrub me!", priority: 2);

        let mucModule: MucModule = client.modulesManager.getModule(MucModule.ID)!;
        _ = mucModule.join(roomName: "room-name", mucServer: "muc.domain.com", nickname: "Test");
    }

    func contactPresenceChanged(_ cpc: PresenceModule.ContactPresenceChanged) {
        print("We got notified that", cpc.presence.from, "changed presence to", cpc.presence.show);
    }

    func messageReceived(_ mr: MessageModule.MessageReceivedEvent) {
        print("Received new message from", mr.message.from, "with text", mr.message.body);

        let messageModule: MessageModule = client.modulesManager.getModule(MessageModule.ID)!;
        print("Creating chat instance if it was not received..");
        let chat = mr.chat ?? messageModule.createChat(with: mr.message.from!);
        print("Sending response..");
        _ = messageModule.sendMessage(in: chat!, body: "Message in response to: " + (mr.message.body ?? ""));
    }

    func mucRoomJoined(_ event: MucModule.YouJoinedEvent) {
        event.room.sendMessage("Welcome to all");
    }

    func mucMessageReceived(_ event: MucModule.MessageReceivedEvent) {
        print("received from", event.nickname, "message", event.message.body);
    }
}

5.5. Simple client with support for PubSub

In this example you can find how to create PubSub node, publish item, receive notifications, retrieve items and delete PubSub node.

import Foundation
import TigaseSwift

class PubSubClient: EventHandler {

    var client: XMPPClient;
    var pubsubJid: BareJID!;
    let nodeName = "test-node1";

    var errorHandler: ((ErrorCondition?,PubSubErrorCondition?)->Void)? = { (errorCondition,pubsubErrorCondition) in
        print("received error: ", errorCondition, pubsubErrorCondition);
    };

    init() {
        Log.initialize();

        client = XMPPClient();

        registerModules();

        print("Notifying event bus that we are interested in SessionEstablishmentSuccessEvent" +
            " which is fired after client is connected");
        client.eventBus.register(handler: self, for: SessionEstablishmentModule.SessionEstablishmentSuccessEvent.TYPE);
        print("Notifying event bus that we are interested in DisconnectedEvent" +
            " which is fired after client is connected");
        client.eventBus.register(handler: self, for: SocketConnector.DisconnectedEvent.TYPE);
        print("Notifying event bus that we are interested in ContactPresenceChangedEvent");
        client.eventBus.register(handler: self, for: PresenceModule.ContactPresenceChanged.TYPE);
        print("Notifying event bus that we are interedted in PubSubModule.NotificationReceivedEvent");
        client.eventBus.register(handler: self, for: PubSubModule.NotificationReceivedEvent.TYPE)

        setCredentials(userJID: "[email protected]", password: "Pa$$w0rd");

        pubsubJid = BareJID("pubsub." + client.sessionObject.userBareJid!.domain);

        print("Connecting to server..")
        client.login();
        print("Started async processing..");
    }

    func registerModules() {
        print("Registering modules required for authentication and session establishment");
        _ = client.modulesManager.register(AuthModule());
        _ = client.modulesManager.register(StreamFeaturesModule());
        _ = client.modulesManager.register(SaslModule());
        _ = client.modulesManager.register(ResourceBinderModule());
        _ = client.modulesManager.register(SessionEstablishmentModule());

        print("Registering module for handling presences..");
        _ = client.modulesManager.register(PresenceModule());
        print("Registering module for handling messages..");
        _ = client.modulesManager.register(MessageModule());
        print("Registering module for handling pubsub protocol..");
        _ = client.modulesManager.register(PubSubModule());
}

    func setCredentials(userJID: String, password: String) {
        let jid = BareJID(userJID);
        client.connectionConfiguration.setUserJID(jid);
        client.connectionConfiguration.setUserPassword(password);
    }

    /// Processing received events
    func handle(event: Event) {
        switch (event) {
        case is SessionEstablishmentModule.SessionEstablishmentSuccessEvent:
            sessionEstablished();
        case is SocketConnector.DisconnectedEvent:
            print("Client is disconnected.");
        case let cpc as PresenceModule.ContactPresenceChanged:
            contactPresenceChanged(cpc);
        case let psne as PubSubModule.NotificationReceivedEvent:
            pubsubNotificationReceived(psne);
        default:
            print("unsupported event", event);
        }
    }

    /// Called when session is established
    func sessionEstablished() {
        print("Now we are connected to server and session is ready..");

        let presenceModule: PresenceModule = client.modulesManager.getModule(PresenceModule.ID)!;
        print("Setting presence to DND...");
        presenceModule.setPresence(show: Presence.Show.dnd, status: "Do not distrub me!", priority: 2);
        self.createPubSubNode();
    }

    func contactPresenceChanged(_ cpc: PresenceModule.ContactPresenceChanged) {
        print("We got notified that", cpc.presence.from, "changed presence to", cpc.presence.show);
    }

    func createPubSubNode() {
        let pubsubModule: PubSubModule = client.modulesManager.getModule(PubSubModule.ID)!;
        pubsubModule.createNode(at: pubsubJid, node: nodeName, onSuccess: { (stanza) in
            print("node", self.nodeName, "created at", self.pubsubJid);
            self.publishItem();
        }, onError: self.errorHandler);
    }

    func publishItem() {
        let pubsubModule: PubSubModule = client.modulesManager.getModule(PubSubModule.ID)!;

        let payload = Element(name: "payload", cdata: "Sample item");

        pubsubModule.publishItem(at: pubsubJid, to: nodeName, payload: payload, onSuccess: { (stanza,node,id) in
            print("published item with id", id, "on node", node, "at", self.pubsubJid);
            self.retrieveItems();
        }, onError: self.errorHandler);
    }

    func retrieveItems() {
        let pubsubModule: PubSubModule = client.modulesManager.getModule(PubSubModule.ID)!;

        pubsubModule.retriveItems(from: pubsubJid, for: nodeName, onSuccess: { (stanza, node, items, rsm) in
            print("retrieved", items.count, " items from", stanza.from, "node", node, "items = ", items);
            self.deletePubSubNode()
        }, onError: self.errorHandler);
    }

    func deletePubSubNode() {
        let pubsubModule: PubSubModule = client.modulesManager.getModule(PubSubModule.ID)!;
        pubsubModule.deleteNode(from: pubsubJid, node: nodeName, onSuccess: { (stanza) in
            print("node", self.nodeName, "deleted from", self.pubsubJid);
        }, onError: self.errorHandler);
    }

    func pubsubNotificationReceived(_ event: PubSubModule.NotificationReceivedEvent) {
        print("received notification event from pubsub node", event.nodeName, "at", event.message.from, "action", event.itemType, "with item id", event.itemId, "and payload", event.payload?.stringValue);
    }
}