1112 lines
48 KiB
Objective-C
1112 lines
48 KiB
Objective-C
#import <Foundation/Foundation.h>
|
|
#import "XMPPSASLAuthentication.h"
|
|
#import "XMPPCustomBinding.h"
|
|
#import "GCDMulticastDelegate.h"
|
|
#import "CocoaAsyncSocket/GCDAsyncSocket.h"
|
|
|
|
#if TARGET_OS_IPHONE
|
|
#import "DDXML.h"
|
|
#endif
|
|
|
|
@class XMPPSRVResolver;
|
|
@class XMPPParser;
|
|
@class XMPPJID;
|
|
@class XMPPIQ;
|
|
@class XMPPMessage;
|
|
@class XMPPPresence;
|
|
@class XMPPModule;
|
|
@class XMPPElement;
|
|
@class XMPPElementReceipt;
|
|
@protocol XMPPStreamDelegate;
|
|
|
|
#if TARGET_OS_IPHONE
|
|
#define MIN_KEEPALIVE_INTERVAL 20.0 // 20 Seconds
|
|
#define DEFAULT_KEEPALIVE_INTERVAL 120.0 // 2 Minutes
|
|
#else
|
|
#define MIN_KEEPALIVE_INTERVAL 10.0 // 10 Seconds
|
|
#define DEFAULT_KEEPALIVE_INTERVAL 300.0 // 5 Minutes
|
|
#endif
|
|
|
|
extern NSString *const XMPPStreamErrorDomain;
|
|
|
|
typedef NS_ENUM(NSUInteger, XMPPStreamErrorCode) {
|
|
XMPPStreamInvalidType, // Attempting to access P2P methods in a non-P2P stream, or vice-versa
|
|
XMPPStreamInvalidState, // Invalid state for requested action, such as connect when already connected
|
|
XMPPStreamInvalidProperty, // Missing a required property, such as myJID
|
|
XMPPStreamInvalidParameter, // Invalid parameter, such as a nil JID
|
|
XMPPStreamUnsupportedAction, // The server doesn't support the requested action
|
|
};
|
|
|
|
typedef NS_ENUM(NSUInteger, XMPPStreamStartTLSPolicy) {
|
|
XMPPStreamStartTLSPolicyAllowed, // TLS will be used if the server requires it
|
|
XMPPStreamStartTLSPolicyPreferred, // TLS will be used if the server offers it
|
|
XMPPStreamStartTLSPolicyRequired // TLS will be used if the server offers it, else the stream won't connect
|
|
};
|
|
|
|
extern const NSTimeInterval XMPPStreamTimeoutNone;
|
|
|
|
@interface XMPPStream : NSObject <GCDAsyncSocketDelegate>
|
|
|
|
/**
|
|
* Standard XMPP initialization.
|
|
* The stream is a standard client to server connection.
|
|
*
|
|
* P2P streams using XEP-0174 are also supported.
|
|
* See the P2P section below.
|
|
**/
|
|
- (id)init;
|
|
|
|
/**
|
|
* Peer to Peer XMPP initialization.
|
|
* The stream is a direct client to client connection as outlined in XEP-0174.
|
|
**/
|
|
- (id)initP2PFrom:(XMPPJID *)myJID;
|
|
|
|
/**
|
|
* XMPPStream uses a multicast delegate.
|
|
* This allows one to add multiple delegates to a single XMPPStream instance,
|
|
* which makes it easier to separate various components and extensions.
|
|
*
|
|
* For example, if you were implementing two different custom extensions on top of XMPP,
|
|
* you could put them in separate classes, and simply add each as a delegate.
|
|
**/
|
|
- (void)addDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
|
|
- (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
|
|
- (void)removeDelegate:(id)delegate;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Properties
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* The server's hostname that should be used to make the TCP connection.
|
|
* This may be a domain name (e.g. "deusty.com") or an IP address (e.g. "70.85.193.226").
|
|
*
|
|
* Note that this may be different from the virtual xmpp hostname.
|
|
* Just as HTTP servers can support mulitple virtual hosts from a single server, so too can xmpp servers.
|
|
* A prime example is google via google apps.
|
|
*
|
|
* For example, say you own the domain "mydomain.com".
|
|
* If you go to mydomain.com in a web browser,
|
|
* you are directed to your apache server running on your webserver somewhere in the cloud.
|
|
* But you use google apps for your email and xmpp needs.
|
|
* So if somebody sends you an email, it actually goes to google's servers, where you later access it from.
|
|
* Similarly, you connect to google's servers to sign into xmpp.
|
|
*
|
|
* In the example above, your hostname is "talk.google.com" and your JID is "me@mydomain.com".
|
|
*
|
|
* This hostName property is optional.
|
|
* If you do not set the hostName, then the framework will follow the xmpp specification using jid's domain.
|
|
* That is, it first do an SRV lookup (as specified in the xmpp RFC).
|
|
* If that fails, it will fall back to simply attempting to connect to the jid's domain.
|
|
**/
|
|
@property (readwrite, copy) NSString *hostName;
|
|
|
|
/**
|
|
* The port the xmpp server is running on.
|
|
* If you do not explicitly set the port, the default port will be used.
|
|
* If you set the port to zero, the default port will be used.
|
|
*
|
|
* The default port is 5222.
|
|
**/
|
|
@property (readwrite, assign) UInt16 hostPort;
|
|
|
|
/**
|
|
* The stream's policy on when to Start TLS.
|
|
*
|
|
* The default is XMPPStreamStartTLSPolicyAllowed.
|
|
*
|
|
* @see XMPPStreamStartTLSPolicy
|
|
**/
|
|
@property (readwrite, assign) XMPPStreamStartTLSPolicy startTLSPolicy;
|
|
|
|
/**
|
|
* The JID of the user.
|
|
*
|
|
* This value is required, and is used in many parts of the underlying implementation.
|
|
* When connecting, the domain of the JID is used to properly specify the correct xmpp virtual host.
|
|
* It is used during registration to supply the username of the user to create an account for.
|
|
* It is used during authentication to supply the username of the user to authenticate with.
|
|
* And the resource may be used post-authentication during the required xmpp resource binding step.
|
|
*
|
|
* A proper JID is of the form user@domain/resource.
|
|
* For example: robbiehanson@deusty.com/work
|
|
*
|
|
* The resource is optional, in the sense that if one is not supplied,
|
|
* one will be automatically generated for you (either by us or by the server).
|
|
*
|
|
* Please note:
|
|
* Resource collisions are handled in different ways depending on server configuration.
|
|
*
|
|
* For example:
|
|
* You are signed in with user1@domain.com/home on your desktop.
|
|
* Then you attempt to sign in with user1@domain.com/home on your laptop.
|
|
*
|
|
* The server could possibly:
|
|
* - Reject the resource request for the laptop.
|
|
* - Accept the resource request for the laptop, and immediately disconnect the desktop.
|
|
* - Automatically assign the laptop another resource without a conflict.
|
|
*
|
|
* For this reason, you may wish to check the myJID variable after the stream has been connected,
|
|
* just in case the resource was changed by the server.
|
|
**/
|
|
@property (readwrite, copy) XMPPJID *myJID;
|
|
|
|
/**
|
|
* Only used in P2P streams.
|
|
**/
|
|
@property (strong, readonly) XMPPJID *remoteJID;
|
|
|
|
/**
|
|
* Many routers will teardown a socket mapping if there is no activity on the socket.
|
|
* For this reason, the xmpp stream supports sending keep-alive data.
|
|
* This is simply whitespace, which is ignored by the xmpp protocol.
|
|
*
|
|
* Keep-alive data is only sent in the absence of any other data being sent/received.
|
|
*
|
|
* The default value is defined in DEFAULT_KEEPALIVE_INTERVAL.
|
|
* The minimum value is defined in MIN_KEEPALIVE_INTERVAL.
|
|
*
|
|
* To disable keep-alive, set the interval to zero (or any non-positive number).
|
|
*
|
|
* The keep-alive timer (if enabled) fires every (keepAliveInterval / 4) seconds.
|
|
* Upon firing it checks when data was last sent/received,
|
|
* and sends keep-alive data if the elapsed time has exceeded the keepAliveInterval.
|
|
* Thus the effective resolution of the keepalive timer is based on the interval.
|
|
*
|
|
* @see keepAliveWhitespaceCharacter
|
|
**/
|
|
@property (readwrite, assign) NSTimeInterval keepAliveInterval;
|
|
|
|
/**
|
|
* The keep-alive mechanism sends whitespace which is ignored by the xmpp protocol.
|
|
* The default whitespace character is a space (' ').
|
|
*
|
|
* This can be changed, for whatever reason, to another whitespace character.
|
|
* Valid whitespace characters are space(' '), tab('\t') and newline('\n').
|
|
*
|
|
* If you attempt to set the character to any non-whitespace character, the attempt is ignored.
|
|
*
|
|
* @see keepAliveInterval
|
|
**/
|
|
@property (readwrite, assign) char keepAliveWhitespaceCharacter;
|
|
|
|
/**
|
|
* Represents the last sent presence element concerning the presence of myJID on the server.
|
|
* In other words, it represents the presence as others see us.
|
|
*
|
|
* This excludes presence elements sent concerning subscriptions, MUC rooms, etc.
|
|
*
|
|
* @see resendMyPresence
|
|
**/
|
|
@property (strong, readonly) XMPPPresence *myPresence;
|
|
|
|
/**
|
|
* Returns the total number of bytes bytes sent/received by the xmpp stream.
|
|
*
|
|
* By default this is the byte count since the xmpp stream object has been created.
|
|
* If the stream has connected/disconnected/reconnected multiple times,
|
|
* the count will be the summation of all connections.
|
|
*
|
|
* The functionality may optionaly be changed to count only the current socket connection.
|
|
* @see resetByteCountPerConnection
|
|
**/
|
|
@property (readonly) uint64_t numberOfBytesSent;
|
|
@property (readonly) uint64_t numberOfBytesReceived;
|
|
|
|
/**
|
|
* Same as the individual properties,
|
|
* but provides a way to fetch them in one atomic operation.
|
|
**/
|
|
- (void)getNumberOfBytesSent:(uint64_t *)bytesSentPtr numberOfBytesReceived:(uint64_t *)bytesReceivedPtr;
|
|
|
|
/**
|
|
* Affects the funtionality of the byte counter.
|
|
*
|
|
* The default value is NO.
|
|
*
|
|
* If set to YES, the byte count will be reset just prior to a new connection (in the connect methods).
|
|
**/
|
|
@property (readwrite, assign) BOOL resetByteCountPerConnection;
|
|
|
|
/**
|
|
* The tag property allows you to associate user defined information with the stream.
|
|
* Tag values are not used internally, and should not be used by xmpp modules.
|
|
**/
|
|
@property (readwrite, strong) id tag;
|
|
|
|
/**
|
|
* RFC 6121 states that starting a session is no longer required.
|
|
* To skip this step set skipStartSession to YES.
|
|
*
|
|
* [RFC3921] specified one additional
|
|
* precondition: formal establishment of an instant messaging and
|
|
* presence session. Implementation and deployment experience has
|
|
* shown that this additional step is unnecessary. However, for
|
|
* backward compatibility an implementation MAY still offer that
|
|
* feature. This enables older software to connect while letting
|
|
* newer software save a round trip.
|
|
*
|
|
* The default value is NO.
|
|
**/
|
|
@property (readwrite, assign) BOOL skipStartSession;
|
|
|
|
/**
|
|
* Validates that a response element is FROM the jid that the request element was sent TO.
|
|
* Supports validating responses when request didn't specify a TO.
|
|
*
|
|
* @see isValidResponseElementFrom:forRequestElementTo:
|
|
* @see isValidResponseElement:forRequestElement:
|
|
*
|
|
* The default value is NO.
|
|
**/
|
|
@property (readwrite, assign) BOOL validatesResponses;
|
|
|
|
#if TARGET_OS_IPHONE
|
|
|
|
/**
|
|
* If set, the kCFStreamNetworkServiceTypeVoIP flags will be set on the underlying CFRead/Write streams.
|
|
*
|
|
* The default value is NO.
|
|
**/
|
|
@property (readwrite, assign) BOOL enableBackgroundingOnSocket;
|
|
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark State
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Returns YES if the connection is closed, and thus no stream is open.
|
|
* If the stream is neither disconnected, nor connected, then a connection is currently being established.
|
|
**/
|
|
- (BOOL)isDisconnected;
|
|
|
|
/**
|
|
* Returns YES is the connection is currently connecting
|
|
**/
|
|
- (BOOL)isConnecting;
|
|
|
|
/**
|
|
* Returns YES if the connection is open, and the stream has been properly established.
|
|
* If the stream is neither disconnected, nor connected, then a connection is currently being established.
|
|
*
|
|
* If this method returns YES, then it is ready for you to start sending and receiving elements.
|
|
**/
|
|
- (BOOL)isConnected;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Connect & Disconnect
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Connects to the configured hostName on the configured hostPort.
|
|
* The timeout is optional. To not time out use XMPPStreamTimeoutNone.
|
|
* If the hostName or myJID are not set, this method will return NO and set the error parameter.
|
|
**/
|
|
- (BOOL)connectWithTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr;
|
|
|
|
/**
|
|
* THIS IS DEPRECATED BY THE XMPP SPECIFICATION.
|
|
*
|
|
* The xmpp specification outlines the proper use of SSL/TLS by negotiating
|
|
* the startTLS upgrade within the stream negotiation.
|
|
* This method exists for those ancient servers that still require the connection to be secured prematurely.
|
|
* The timeout is optional. To not time out use XMPPStreamTimeoutNone.
|
|
*
|
|
* Note: Such servers generally use port 5223 for this, which you will need to set.
|
|
**/
|
|
- (BOOL)oldSchoolSecureConnectWithTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr;
|
|
|
|
/**
|
|
* Starts a P2P connection to the given user and given address.
|
|
* The timeout is optional. To not time out use XMPPStreamTimeoutNone.
|
|
* This method only works with XMPPStream objects created using the initP2P method.
|
|
*
|
|
* The given address is specified as a sockaddr structure wrapped in a NSData object.
|
|
* For example, a NSData object returned from NSNetservice's addresses method.
|
|
**/
|
|
- (BOOL)connectTo:(XMPPJID *)remoteJID
|
|
withAddress:(NSData *)remoteAddr
|
|
withTimeout:(NSTimeInterval)timeout
|
|
error:(NSError **)errPtr;
|
|
|
|
/**
|
|
* Starts a P2P connection with the given accepted socket.
|
|
* This method only works with XMPPStream objects created using the initP2P method.
|
|
*
|
|
* The given socket should be a socket that has already been accepted.
|
|
* The remoteJID will be extracted from the opening stream negotiation.
|
|
**/
|
|
- (BOOL)connectP2PWithSocket:(GCDAsyncSocket *)acceptedSocket error:(NSError **)errPtr;
|
|
|
|
/**
|
|
* Disconnects from the remote host by closing the underlying TCP socket connection.
|
|
* The terminating </stream:stream> element is not sent to the server.
|
|
*
|
|
* This method is synchronous.
|
|
* Meaning that the disconnect will happen immediately, even if there are pending elements yet to be sent.
|
|
*
|
|
* The xmppStreamDidDisconnect:withError: delegate method will immediately be dispatched onto the delegate queue.
|
|
**/
|
|
- (void)disconnect;
|
|
|
|
/**
|
|
* Disconnects from the remote host by sending the terminating </stream:stream> element,
|
|
* and then closing the underlying TCP socket connection.
|
|
*
|
|
* This method is asynchronous.
|
|
* The disconnect will happen after all pending elements have been sent.
|
|
* Attempting to send elements after this method has been called will not work (the elements won't get sent).
|
|
**/
|
|
- (void)disconnectAfterSending;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Security
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Returns YES if SSL/TLS was used to establish a connection to the server.
|
|
*
|
|
* Some servers may require an "upgrade to TLS" in order to start communication,
|
|
* so even if the connection was not explicitly secured, an ugrade to TLS may have occured.
|
|
*
|
|
* See also the xmppStream:willSecureWithSettings: delegate method.
|
|
**/
|
|
- (BOOL)isSecure;
|
|
|
|
/**
|
|
* Returns whether or not the server supports securing the connection via SSL/TLS.
|
|
*
|
|
* Some servers will actually require a secure connection,
|
|
* in which case the stream will attempt to secure the connection during the opening process.
|
|
*
|
|
* If the connection has already been secured, this method may return NO.
|
|
**/
|
|
- (BOOL)supportsStartTLS;
|
|
|
|
/**
|
|
* Attempts to secure the connection via SSL/TLS.
|
|
*
|
|
* This method is asynchronous.
|
|
* The SSL/TLS handshake will occur in the background, and
|
|
* the xmppStreamDidSecure: delegate method will be called after the TLS process has completed.
|
|
*
|
|
* This method returns immediately.
|
|
* If the secure process was started, it will return YES.
|
|
* If there was an issue while starting the security process,
|
|
* this method will return NO and set the error parameter.
|
|
*
|
|
* The errPtr parameter is optional - you may pass nil.
|
|
*
|
|
* You may wish to configure the security settings via the xmppStream:willSecureWithSettings: delegate method.
|
|
*
|
|
* If the SSL/TLS handshake fails, the connection will be closed.
|
|
* The reason for the error will be reported via the xmppStreamDidDisconnect:withError: delegate method.
|
|
* The error parameter will be an NSError object, and may have an error domain of kCFStreamErrorDomainSSL.
|
|
* The corresponding error code is documented in Apple's Security framework, in SecureTransport.h
|
|
**/
|
|
- (BOOL)secureConnection:(NSError **)errPtr;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Registration
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* In Band Registration.
|
|
* Creating a user account on the xmpp server within the xmpp protocol.
|
|
*
|
|
* The registerWithElements:error: method is asynchronous.
|
|
* It will return immediately, and the delegate methods are used to determine success.
|
|
* See the xmppStreamDidRegister: and xmppStream:didNotRegister: methods.
|
|
*
|
|
* If there is something immediately wrong, such as the stream is not connected,
|
|
* this method will return NO and set the error.
|
|
*
|
|
* The errPtr parameter is optional - you may pass nil.
|
|
*
|
|
* registerWithPassword:error: is a convience method for creating an account using the given username and password.
|
|
*
|
|
* Security Note:
|
|
* The password will be sent in the clear unless the stream has been secured.
|
|
**/
|
|
- (BOOL)supportsInBandRegistration;
|
|
- (BOOL)registerWithElements:(NSArray *)elements error:(NSError **)errPtr;
|
|
- (BOOL)registerWithPassword:(NSString *)password error:(NSError **)errPtr;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Authentication
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Returns the server's list of supported authentication mechanisms.
|
|
* Each item in the array will be of type NSString.
|
|
*
|
|
* For example, if the server supplied this stanza within it's reported stream:features:
|
|
*
|
|
* <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
|
|
* <mechanism>DIGEST-MD5</mechanism>
|
|
* <mechanism>PLAIN</mechanism>
|
|
* </mechanisms>
|
|
*
|
|
* Then this method would return [@"DIGEST-MD5", @"PLAIN"].
|
|
**/
|
|
- (NSArray *)supportedAuthenticationMechanisms;
|
|
|
|
/**
|
|
* Returns whether or not the given authentication mechanism name was specified in the
|
|
* server's list of supported authentication mechanisms.
|
|
*
|
|
* Note: The authentication classes often provide a category on XMPPStream, adding useful methods.
|
|
*
|
|
* @see XMPPPlainAuthentication - supportsPlainAuthentication
|
|
* @see XMPPDigestMD5Authentication - supportsDigestMD5Authentication
|
|
* @see XMPPXFacebookPlatformAuthentication - supportsXFacebookPlatformAuthentication
|
|
* @see XMPPDeprecatedPlainAuthentication - supportsDeprecatedPlainAuthentication
|
|
* @see XMPPDeprecatedDigestAuthentication - supportsDeprecatedDigestAuthentication
|
|
**/
|
|
- (BOOL)supportsAuthenticationMechanism:(NSString *)mechanism;
|
|
|
|
/**
|
|
* This is the root authentication method.
|
|
* All other authentication methods go through this one.
|
|
*
|
|
* This method attempts to start the authentication process given the auth instance.
|
|
* That is, this method will invoke start: on the given auth instance.
|
|
* If it returns YES, then the stream will enter into authentication mode.
|
|
* It will then continually invoke the handleAuth: method on the given instance until authentication is complete.
|
|
*
|
|
* This method is asynchronous.
|
|
*
|
|
* If there is something immediately wrong, such as the stream is not connected,
|
|
* the method will return NO and set the error.
|
|
* Otherwise the delegate callbacks are used to communicate auth success or failure.
|
|
*
|
|
* @see xmppStreamDidAuthenticate:
|
|
* @see xmppStream:didNotAuthenticate:
|
|
*
|
|
* @see authenticateWithPassword:error:
|
|
*
|
|
* Note: The security process is abstracted in order to provide flexibility,
|
|
* and allow developers to easily implement their own custom authentication protocols.
|
|
* The authentication classes often provide a category on XMPPStream, adding useful methods.
|
|
*
|
|
* @see XMPPXFacebookPlatformAuthentication - authenticateWithFacebookAccessToken:error:
|
|
**/
|
|
- (BOOL)authenticate:(id <XMPPSASLAuthentication>)auth error:(NSError **)errPtr;
|
|
|
|
/**
|
|
* This method applies to standard password authentication schemes only.
|
|
* This is NOT the primary authentication method.
|
|
*
|
|
* @see authenticate:error:
|
|
*
|
|
* This method exists for backwards compatibility, and may disappear in future versions.
|
|
**/
|
|
- (BOOL)authenticateWithPassword:(NSString *)password error:(NSError **)errPtr;
|
|
|
|
/**
|
|
* Returns whether or not the xmpp stream is currently authenticating with the XMPP Server.
|
|
**/
|
|
- (BOOL)isAuthenticating;
|
|
|
|
/**
|
|
* Returns whether or not the xmpp stream has successfully authenticated with the server.
|
|
**/
|
|
- (BOOL)isAuthenticated;
|
|
|
|
/**
|
|
* Returns the date when the xmpp stream successfully authenticated with the server.
|
|
**/
|
|
- (NSDate *)authenticationDate;
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Compression
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/**
|
|
* Returns the server's list of supported compression methods in accordance to XEP-0138: Stream Compression
|
|
* Each item in the array will be of type NSString.
|
|
*
|
|
* For example, if the server supplied this stanza within it's reported stream:features:
|
|
*
|
|
* <compression xmlns='http://jabber.org/features/compress'>
|
|
* <method>zlib</method>
|
|
* <method>lzw</method>
|
|
* </compression>
|
|
*
|
|
* Then this method would return [@"zlib", @"lzw"].
|
|
**/
|
|
- (NSArray *)supportedCompressionMethods;
|
|
|
|
|
|
/**
|
|
* Returns whether or not the given compression method name was specified in the
|
|
* server's list of supported compression methods.
|
|
*
|
|
* Note: The XMPPStream doesn't currently support any compression methods
|
|
**/
|
|
|
|
- (BOOL)supportsCompressionMethod:(NSString *)compressionMethod;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Server Info
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* This method will return the root element of the document.
|
|
* This element contains the opening <stream:stream/> and <stream:features/> tags received from the server.
|
|
*
|
|
* If multiple <stream:features/> have been received during the course of stream negotiation,
|
|
* the root element contains only the most recent (current) version.
|
|
*
|
|
* Note: The rootElement is "empty", in-so-far as it does not contain all the XML elements the stream has
|
|
* received during it's connection. This is done for performance reasons and for the obvious benefit
|
|
* of being more memory efficient.
|
|
**/
|
|
- (NSXMLElement *)rootElement;
|
|
|
|
/**
|
|
* Returns the version attribute from the servers's <stream:stream/> element.
|
|
* This should be at least 1.0 to be RFC 3920 compliant.
|
|
* If no version number was set, the server is not RFC compliant, and 0 is returned.
|
|
**/
|
|
- (float)serverXmppStreamVersionNumber;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Sending
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Sends the given XML element.
|
|
* If the stream is not yet connected, this method does nothing.
|
|
**/
|
|
- (void)sendElement:(NSXMLElement *)element;
|
|
|
|
/**
|
|
* Just like the sendElement: method above,
|
|
* but allows you to receive a receipt that can later be used to verify the element has been sent.
|
|
*
|
|
* If you later want to check to see if the element has been sent:
|
|
*
|
|
* if ([receipt wait:0]) {
|
|
* // Element has been sent
|
|
* }
|
|
*
|
|
* If you later want to wait until the element has been sent:
|
|
*
|
|
* if ([receipt wait:-1]) {
|
|
* // Element was sent
|
|
* } else {
|
|
* // Element failed to send due to disconnection
|
|
* }
|
|
*
|
|
* It is important to understand what it means when [receipt wait:timeout] returns YES.
|
|
* It does NOT mean the server has received the element.
|
|
* It only means the data has been queued for sending in the underlying OS socket buffer.
|
|
*
|
|
* So at this point the OS will do everything in its capacity to send the data to the server,
|
|
* which generally means the server will eventually receive the data.
|
|
* Unless, of course, something horrible happens such as a network failure,
|
|
* or a system crash, or the server crashes, etc.
|
|
*
|
|
* Even if you close the xmpp stream after this point, the OS will still do everything it can to send the data.
|
|
**/
|
|
- (void)sendElement:(NSXMLElement *)element andGetReceipt:(XMPPElementReceipt **)receiptPtr;
|
|
|
|
/**
|
|
* Fetches and resends the myPresence element (if available) in a single atomic operation.
|
|
*
|
|
* There are various xmpp extensions that hook into the xmpp stream and append information to outgoing presence stanzas.
|
|
* For example, the XMPPCapabilities module automatically appends capabilities information (as a hash).
|
|
* When these modules need to update/change their appended information,
|
|
* they should use this method to do so.
|
|
*
|
|
* The alternative is to fetch the myPresence element, and resend it manually using the sendElement method.
|
|
* However, that is 2 seperate operations, and the user, may send a different presence element inbetween.
|
|
* Using this method guarantees everything is done as an atomic operation.
|
|
**/
|
|
- (void)resendMyPresence;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Stanza Validation
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Validates that a response element is FROM the jid that the request element was sent TO.
|
|
* Supports validating responses when request didn't specify a TO.
|
|
**/
|
|
- (BOOL)isValidResponseElementFrom:(XMPPJID *)from forRequestElementTo:(XMPPJID *)to;
|
|
|
|
- (BOOL)isValidResponseElement:(XMPPElement *)response forRequestElement:(XMPPElement *)request;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Module Plug-In System
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* The XMPPModule class automatically invokes these methods when it is activated/deactivated.
|
|
*
|
|
* The registerModule method registers the module with the xmppStream.
|
|
* If there are any other modules that have requested to be automatically added as delegates to modules of this type,
|
|
* then those modules are automatically added as delegates during the asynchronous execution of this method.
|
|
*
|
|
* The registerModule method is asynchronous.
|
|
*
|
|
* The unregisterModule method unregisters the module with the xmppStream,
|
|
* and automatically removes it as a delegate of any other module.
|
|
*
|
|
* The unregisterModule method is fully synchronous.
|
|
* That is, after this method returns, the module will not be scheduled in any more delegate calls from other modules.
|
|
* However, if the module was already scheduled in an existing asynchronous delegate call from another module,
|
|
* the scheduled delegate invocation remains queued and will fire in the near future.
|
|
* Since the delegate invocation is already queued,
|
|
* the module's retainCount has been incremented,
|
|
* and the module will not be deallocated until after the delegate invocation has fired.
|
|
**/
|
|
- (void)registerModule:(XMPPModule *)module;
|
|
- (void)unregisterModule:(XMPPModule *)module;
|
|
|
|
/**
|
|
* Automatically registers the given delegate with all current and future registered modules of the given class.
|
|
*
|
|
* That is, the given delegate will be added to the delegate list ([module addDelegate:delegate delegateQueue:dq]) to
|
|
* all current and future registered modules that respond YES to [module isKindOfClass:aClass].
|
|
*
|
|
* This method is used by modules to automatically integrate with other modules.
|
|
* For example, a module may auto-add itself as a delegate to XMPPCapabilities
|
|
* so that it can broadcast its implemented features.
|
|
*
|
|
* This may also be useful to clients, for example, to add a delegate to instances of something like XMPPChatRoom,
|
|
* where there may be multiple instances of the module that get created during the course of an xmpp session.
|
|
*
|
|
* If you auto register on multiple queues, you can remove all registrations with a single
|
|
* call to removeAutoDelegate::: by passing NULL as the 'dq' parameter.
|
|
*
|
|
* If you auto register for multiple classes, you can remove all registrations with a single
|
|
* call to removeAutoDelegate::: by passing nil as the 'aClass' parameter.
|
|
**/
|
|
- (void)autoAddDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue toModulesOfClass:(Class)aClass;
|
|
- (void)removeAutoDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue fromModulesOfClass:(Class)aClass;
|
|
|
|
/**
|
|
* Allows for enumeration of the currently registered modules.
|
|
*
|
|
* This may be useful if the stream needs to be queried for modules of a particular type.
|
|
**/
|
|
- (void)enumerateModulesWithBlock:(void (^)(XMPPModule *module, NSUInteger idx, BOOL *stop))block;
|
|
|
|
/**
|
|
* Allows for enumeration of the currently registered modules that are a kind of Class.
|
|
* idx is in relation to all modules not just those of the given class.
|
|
**/
|
|
- (void)enumerateModulesOfClass:(Class)aClass withBlock:(void (^)(XMPPModule *module, NSUInteger idx, BOOL *stop))block;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Utilities
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Generates and returns a new autoreleased UUID.
|
|
* UUIDs (Universally Unique Identifiers) may also be known as GUIDs (Globally Unique Identifiers).
|
|
*
|
|
* The UUID is generated using the CFUUID library, which generates a unique 128 bit value.
|
|
* The uuid is then translated into a string using the standard format for UUIDs:
|
|
* "68753A44-4D6F-1226-9C60-0050E4C00067"
|
|
*
|
|
* This method is most commonly used to generate a unique id value for an xmpp element.
|
|
**/
|
|
+ (NSString *)generateUUID;
|
|
- (NSString *)generateUUID;
|
|
|
|
@end
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark -
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
@interface XMPPElementReceipt : NSObject
|
|
{
|
|
uint32_t atomicFlags;
|
|
dispatch_semaphore_t semaphore;
|
|
}
|
|
|
|
/**
|
|
* Element receipts allow you to check to see if the element has been sent.
|
|
* The timeout parameter allows you to do any of the following:
|
|
*
|
|
* - Do an instantaneous check (pass timeout == 0)
|
|
* - Wait until the element has been sent (pass timeout < 0)
|
|
* - Wait up to a certain amount of time (pass timeout > 0)
|
|
*
|
|
* It is important to understand what it means when [receipt wait:timeout] returns YES.
|
|
* It does NOT mean the server has received the element.
|
|
* It only means the data has been queued for sending in the underlying OS socket buffer.
|
|
*
|
|
* So at this point the OS will do everything in its capacity to send the data to the server,
|
|
* which generally means the server will eventually receive the data.
|
|
* Unless, of course, something horrible happens such as a network failure,
|
|
* or a system crash, or the server crashes, etc.
|
|
*
|
|
* Even if you close the xmpp stream after this point, the OS will still do everything it can to send the data.
|
|
**/
|
|
- (BOOL)wait:(NSTimeInterval)timeout;
|
|
|
|
@end
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark -
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
@protocol XMPPStreamDelegate
|
|
@optional
|
|
|
|
/**
|
|
* This method is called before the stream begins the connection process.
|
|
*
|
|
* If developing an iOS app that runs in the background, this may be a good place to indicate
|
|
* that this is a task that needs to continue running in the background.
|
|
**/
|
|
- (void)xmppStreamWillConnect:(XMPPStream *)sender;
|
|
|
|
/**
|
|
* This method is called after the tcp socket has connected to the remote host.
|
|
* It may be used as a hook for various things, such as updating the UI or extracting the server's IP address.
|
|
*
|
|
* If developing an iOS app that runs in the background,
|
|
* please use XMPPStream's enableBackgroundingOnSocket property as opposed to doing it directly on the socket here.
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket;
|
|
|
|
/**
|
|
* This method is called after a TCP connection has been established with the server,
|
|
* and the opening XML stream negotiation has started.
|
|
**/
|
|
- (void)xmppStreamDidStartNegotiation:(XMPPStream *)sender;
|
|
|
|
/**
|
|
* This method is called immediately prior to the stream being secured via TLS/SSL.
|
|
* Note that this delegate may be called even if you do not explicitly invoke the startTLS method.
|
|
* Servers have the option of requiring connections to be secured during the opening process.
|
|
* If this is the case, the XMPPStream will automatically attempt to properly secure the connection.
|
|
*
|
|
* The dictionary of settings is what will be passed to the startTLS method of the underlying GCDAsyncSocket.
|
|
* The GCDAsyncSocket header file contains a discussion of the available key/value pairs,
|
|
* as well as the security consequences of various options.
|
|
* It is recommended reading if you are planning on implementing this method.
|
|
*
|
|
* The dictionary of settings that are initially passed will be an empty dictionary.
|
|
* If you choose not to implement this method, or simply do not edit the dictionary,
|
|
* then the default settings will be used.
|
|
* That is, the kCFStreamSSLPeerName will be set to the configured host name,
|
|
* and the default security validation checks will be performed.
|
|
*
|
|
* This means that authentication will fail if the name on the X509 certificate of
|
|
* the server does not match the value of the hostname for the xmpp stream.
|
|
* It will also fail if the certificate is self-signed, or if it is expired, etc.
|
|
*
|
|
* These settings are most likely the right fit for most production environments,
|
|
* but may need to be tweaked for development or testing,
|
|
* where the development server may be using a self-signed certificate.
|
|
*
|
|
* Note: If your development server is using a self-signed certificate,
|
|
* you likely need to add GCDAsyncSocketManuallyEvaluateTrust=YES to the settings.
|
|
* Then implement the xmppStream:didReceiveTrust:completionHandler: delegate method to perform custom validation.
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:(NSMutableDictionary *)settings;
|
|
|
|
/**
|
|
* Allows a delegate to hook into the TLS handshake and manually validate the peer it's connecting to.
|
|
*
|
|
* This is only called if the stream is secured with settings that include:
|
|
* - GCDAsyncSocketManuallyEvaluateTrust == YES
|
|
* That is, if a delegate implements xmppStream:willSecureWithSettings:, and plugs in that key/value pair.
|
|
*
|
|
* Thus this delegate method is forwarding the TLS evaluation callback from the underlying GCDAsyncSocket.
|
|
*
|
|
* Typically the delegate will use SecTrustEvaluate (and related functions) to properly validate the peer.
|
|
*
|
|
* Note from Apple's documentation:
|
|
* Because [SecTrustEvaluate] might look on the network for certificates in the certificate chain,
|
|
* [it] might block while attempting network access. You should never call it from your main thread;
|
|
* call it only from within a function running on a dispatch queue or on a separate thread.
|
|
*
|
|
* This is why this method uses a completionHandler block rather than a normal return value.
|
|
* The idea is that you should be performing SecTrustEvaluate on a background thread.
|
|
* The completionHandler block is thread-safe, and may be invoked from a background queue/thread.
|
|
* It is safe to invoke the completionHandler block even if the socket has been closed.
|
|
*
|
|
* Keep in mind that you can do all kinds of cool stuff here.
|
|
* For example:
|
|
*
|
|
* If your development server is using a self-signed certificate,
|
|
* then you could embed info about the self-signed cert within your app, and use this callback to ensure that
|
|
* you're actually connecting to the expected dev server.
|
|
*
|
|
* Also, you could present certificates that don't pass SecTrustEvaluate to the client.
|
|
* That is, if SecTrustEvaluate comes back with problems, you could invoke the completionHandler with NO,
|
|
* and then ask the client if the cert can be trusted. This is similar to how most browsers act.
|
|
*
|
|
* Generally, only one delegate should implement this method.
|
|
* However, if multiple delegates implement this method, then the first to invoke the completionHandler "wins".
|
|
* And subsequent invocations of the completionHandler are ignored.
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender didReceiveTrust:(SecTrustRef)trust
|
|
completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler;
|
|
|
|
/**
|
|
* This method is called after the stream has been secured via SSL/TLS.
|
|
* This method may be called if the server required a secure connection during the opening process,
|
|
* or if the secureConnection: method was manually invoked.
|
|
**/
|
|
- (void)xmppStreamDidSecure:(XMPPStream *)sender;
|
|
|
|
/**
|
|
* This method is called after the XML stream has been fully opened.
|
|
* More precisely, this method is called after an opening <xml/> and <stream:stream/> tag have been sent and received,
|
|
* and after the stream features have been received, and any required features have been fullfilled.
|
|
* At this point it's safe to begin communication with the server.
|
|
**/
|
|
- (void)xmppStreamDidConnect:(XMPPStream *)sender;
|
|
|
|
/**
|
|
* This method is called after registration of a new user has successfully finished.
|
|
* If registration fails for some reason, the xmppStream:didNotRegister: method will be called instead.
|
|
**/
|
|
- (void)xmppStreamDidRegister:(XMPPStream *)sender;
|
|
|
|
/**
|
|
* This method is called if registration fails.
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error;
|
|
|
|
/**
|
|
* This method is called after authentication has successfully finished.
|
|
* If authentication fails for some reason, the xmppStream:didNotAuthenticate: method will be called instead.
|
|
**/
|
|
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender;
|
|
|
|
/**
|
|
* This method is called if authentication fails.
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error;
|
|
|
|
/**
|
|
* Binding a JID resource is a standard part of the authentication process,
|
|
* and occurs after SASL authentication completes (which generally authenticates the JID username).
|
|
*
|
|
* This delegate method allows for a custom binding procedure to be used.
|
|
* For example:
|
|
* - a custom SASL authentication scheme might combine auth with binding
|
|
* - stream management (xep-0198) replaces binding if it can resume a previous session
|
|
*
|
|
* Return nil (or don't implement this method) if you wish to use the standard binding procedure.
|
|
**/
|
|
- (id <XMPPCustomBinding>)xmppStreamWillBind:(XMPPStream *)sender;
|
|
|
|
/**
|
|
* This method is called if the XMPP server doesn't allow our resource of choice
|
|
* because it conflicts with an existing resource.
|
|
*
|
|
* Return an alternative resource or return nil to let the server automatically pick a resource for us.
|
|
**/
|
|
- (NSString *)xmppStream:(XMPPStream *)sender alternativeResourceForConflictingResource:(NSString *)conflictingResource;
|
|
|
|
/**
|
|
* These methods are called before their respective XML elements are broadcast as received to the rest of the stack.
|
|
* These methods can be used to modify elements on the fly.
|
|
* (E.g. perform custom decryption so the rest of the stack sees readable text.)
|
|
*
|
|
* You may also filter incoming elements by returning nil.
|
|
*
|
|
* When implementing these methods to modify the element, you do not need to copy the given element.
|
|
* You can simply edit the given element, and return it.
|
|
* The reason these methods return an element, instead of void, is to allow filtering.
|
|
*
|
|
* Concerning thread-safety, delegates implementing the method are invoked one-at-a-time to
|
|
* allow thread-safe modification of the given elements.
|
|
*
|
|
* You should NOT implement these methods unless you have good reason to do so.
|
|
* For general processing and notification of received elements, please use xmppStream:didReceiveX: methods.
|
|
*
|
|
* @see xmppStream:didReceiveIQ:
|
|
* @see xmppStream:didReceiveMessage:
|
|
* @see xmppStream:didReceivePresence:
|
|
**/
|
|
- (XMPPIQ *)xmppStream:(XMPPStream *)sender willReceiveIQ:(XMPPIQ *)iq;
|
|
- (XMPPMessage *)xmppStream:(XMPPStream *)sender willReceiveMessage:(XMPPMessage *)message;
|
|
- (XMPPPresence *)xmppStream:(XMPPStream *)sender willReceivePresence:(XMPPPresence *)presence;
|
|
|
|
/**
|
|
* This method is called if any of the xmppStream:willReceiveX: methods filter the incoming stanza.
|
|
*
|
|
* It may be useful for some extensions to know that something was received,
|
|
* even if it was filtered for some reason.
|
|
**/
|
|
- (void)xmppStreamDidFilterStanza:(XMPPStream *)sender;
|
|
|
|
/**
|
|
* These methods are called after their respective XML elements are received on the stream.
|
|
*
|
|
* In the case of an IQ, the delegate method should return YES if it has or will respond to the given IQ.
|
|
* If the IQ is of type 'get' or 'set', and no delegates respond to the IQ,
|
|
* then xmpp stream will automatically send an error response.
|
|
*
|
|
* Concerning thread-safety, delegates shouldn't modify the given elements.
|
|
* As documented in NSXML / KissXML, elements are read-access thread-safe, but write-access thread-unsafe.
|
|
* If you have need to modify an element for any reason,
|
|
* you should copy the element first, and then modify and use the copy.
|
|
**/
|
|
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq;
|
|
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message;
|
|
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence;
|
|
|
|
/**
|
|
* This method is called if an XMPP error is received.
|
|
* In other words, a <stream:error/>.
|
|
*
|
|
* However, this method may also be called for any unrecognized xml stanzas.
|
|
*
|
|
* Note that standard errors (<iq type='error'/> for example) are delivered normally,
|
|
* via the other didReceive...: methods.
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender didReceiveError:(NSXMLElement *)error;
|
|
|
|
/**
|
|
* These methods are called before their respective XML elements are sent over the stream.
|
|
* These methods can be used to modify outgoing elements on the fly.
|
|
* (E.g. add standard information for custom protocols.)
|
|
*
|
|
* You may also filter outgoing elements by returning nil.
|
|
*
|
|
* When implementing these methods to modify the element, you do not need to copy the given element.
|
|
* You can simply edit the given element, and return it.
|
|
* The reason these methods return an element, instead of void, is to allow filtering.
|
|
*
|
|
* Concerning thread-safety, delegates implementing the method are invoked one-at-a-time to
|
|
* allow thread-safe modification of the given elements.
|
|
*
|
|
* You should NOT implement these methods unless you have good reason to do so.
|
|
* For general processing and notification of sent elements, please use xmppStream:didSendX: methods.
|
|
*
|
|
* @see xmppStream:didSendIQ:
|
|
* @see xmppStream:didSendMessage:
|
|
* @see xmppStream:didSendPresence:
|
|
**/
|
|
- (XMPPIQ *)xmppStream:(XMPPStream *)sender willSendIQ:(XMPPIQ *)iq;
|
|
- (XMPPMessage *)xmppStream:(XMPPStream *)sender willSendMessage:(XMPPMessage *)message;
|
|
- (XMPPPresence *)xmppStream:(XMPPStream *)sender willSendPresence:(XMPPPresence *)presence;
|
|
|
|
/**
|
|
* These methods are called after their respective XML elements are sent over the stream.
|
|
* These methods may be used to listen for certain events (such as an unavailable presence having been sent),
|
|
* or for general logging purposes. (E.g. a central history logging mechanism).
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender didSendIQ:(XMPPIQ *)iq;
|
|
- (void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message;
|
|
- (void)xmppStream:(XMPPStream *)sender didSendPresence:(XMPPPresence *)presence;
|
|
|
|
/**
|
|
* These methods are called after failing to send the respective XML elements over the stream.
|
|
* This occurs when the stream gets disconnected before the element can get sent out.
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender didFailToSendIQ:(XMPPIQ *)iq error:(NSError *)error;
|
|
- (void)xmppStream:(XMPPStream *)sender didFailToSendMessage:(XMPPMessage *)message error:(NSError *)error;
|
|
- (void)xmppStream:(XMPPStream *)sender didFailToSendPresence:(XMPPPresence *)presence error:(NSError *)error;
|
|
|
|
/**
|
|
* This method is called if the XMPP Stream's jid changes.
|
|
**/
|
|
- (void)xmppStreamDidChangeMyJID:(XMPPStream *)xmppStream;
|
|
|
|
/**
|
|
* This method is called if the disconnect method is called.
|
|
* It may be used to determine if a disconnection was purposeful, or due to an error.
|
|
*
|
|
* Note: A disconnect may be either "clean" or "dirty".
|
|
* A "clean" disconnect is when the stream sends the closing </stream:stream> stanza before disconnecting.
|
|
* A "dirty" disconnect is when the stream simply closes its TCP socket.
|
|
* In most cases it makes no difference how the disconnect occurs,
|
|
* but there are a few contexts in which the difference has various protocol implications.
|
|
*
|
|
* @see xmppStreamDidSendClosingStreamStanza
|
|
**/
|
|
- (void)xmppStreamWasToldToDisconnect:(XMPPStream *)sender;
|
|
|
|
/**
|
|
* This method is called after the stream has sent the closing </stream:stream> stanza.
|
|
* This signifies a "clean" disconnect.
|
|
*
|
|
* Note: A disconnect may be either "clean" or "dirty".
|
|
* A "clean" disconnect is when the stream sends the closing </stream:stream> stanza before disconnecting.
|
|
* A "dirty" disconnect is when the stream simply closes its TCP socket.
|
|
* In most cases it makes no difference how the disconnect occurs,
|
|
* but there are a few contexts in which the difference has various protocol implications.
|
|
**/
|
|
- (void)xmppStreamDidSendClosingStreamStanza:(XMPPStream *)sender;
|
|
|
|
/**
|
|
* This method is called if the XMPP stream's connect times out.
|
|
**/
|
|
- (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender;
|
|
|
|
/**
|
|
* This method is called after the stream is closed.
|
|
*
|
|
* The given error parameter will be non-nil if the error was due to something outside the general xmpp realm.
|
|
* Some examples:
|
|
* - The TCP socket was unexpectedly disconnected.
|
|
* - The SRV resolution of the domain failed.
|
|
* - Error parsing xml sent from server.
|
|
*
|
|
* @see xmppStreamConnectDidTimeout:
|
|
**/
|
|
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error;
|
|
|
|
/**
|
|
* This method is only used in P2P mode when the connectTo:withAddress: method was used.
|
|
*
|
|
* It allows the delegate to read the <stream:features/> element if/when they arrive.
|
|
* Recall that the XEP specifies that <stream:features/> SHOULD be sent.
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender didReceiveP2PFeatures:(NSXMLElement *)streamFeatures;
|
|
|
|
/**
|
|
* This method is only used in P2P mode when the connectTo:withSocket: method was used.
|
|
*
|
|
* It allows the delegate to customize the <stream:features/> element,
|
|
* adding any specific featues the delegate might support.
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender willSendP2PFeatures:(NSXMLElement *)streamFeatures;
|
|
|
|
/**
|
|
* These methods are called as xmpp modules are registered and unregistered with the stream.
|
|
* This generally corresponds to xmpp modules being initailzed and deallocated.
|
|
*
|
|
* The methods may be useful, for example, if a more precise auto delegation mechanism is needed
|
|
* than what is available with the autoAddDelegate:toModulesOfClass: method.
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender didRegisterModule:(id)module;
|
|
- (void)xmppStream:(XMPPStream *)sender willUnregisterModule:(id)module;
|
|
|
|
/**
|
|
* Custom elements are Non-XMPP elements.
|
|
* In other words, not <iq>, <message> or <presence> elements.
|
|
*
|
|
* Typically these kinds of elements are not allowed by the XMPP server.
|
|
* But some custom implementations may use them.
|
|
* The standard example is XEP-0198, which uses <r> & <a> elements.
|
|
*
|
|
* If you're using custom elements, you must register the custom element name(s).
|
|
* Otherwise the xmppStream will treat non-XMPP elements as errors (xmppStream:didReceiveError:).
|
|
*
|
|
* @see registerCustomElementNames (in XMPPInternal.h)
|
|
**/
|
|
- (void)xmppStream:(XMPPStream *)sender didSendCustomElement:(NSXMLElement *)element;
|
|
- (void)xmppStream:(XMPPStream *)sender didReceiveCustomElement:(NSXMLElement *)element;
|
|
|
|
@end
|