/External/XMPPFramework/Core/XMPPStream.h
C Header | 981 lines | 152 code | 105 blank | 724 comment | 0 complexity | f4314c1c39f9617b2f3ff7742baac8c1 MD5 | raw file
- #import <Foundation/Foundation.h>
- #import "XMPPSASLAuthentication.h"
- #import "GCDAsyncSocket.h"
- #import "GCDMulticastDelegate.h"
- #if TARGET_OS_IPHONE
- #import "DDXML.h"
- #endif
- @class XMPPSRVResolver;
- @class XMPPParser;
- @class XMPPJID;
- @class XMPPIQ;
- @class XMPPMessage;
- @class XMPPPresence;
- @class XMPPModule;
- @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;
- enum 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 enum XMPPStreamErrorCode XMPPStreamErrorCode;
- 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;
- /**
- * Start TLS is used if the server supports it, regardless of wether it is required or not.
- *
- * The default is NO
- **/
- @property (readwrite, assign) BOOL autoStartTLS;
- /**
- * 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 the resetByteCountPerConnection property.
- **/
- @property (readonly) UInt64 numberOfBytesSent;
- @property (readonly) UInt64 numberOfBytesReceived;
- /**
- * 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;
- #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 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;
- /**
- * The XMPP Framework is designed to be entirely GCD based.
- * However, there are various utility classes provided by Apple that are still dependent upon a thread/runloop model.
- * For example, monitoring a network for changes related to connectivity requires we register a runloop-based delegate.
- * Thus XMPPStream creates a dedicated thread/runloop for any xmpp classes that may need it.
- * This provides multiple benefits:
- *
- * - Development is simplified for those transitioning from previous thread/runloop versions.
- * - Development is simplified for those who rely on utility classes that don't yet support pure GCD,
- * as they don't have to setup and maintain a thread/runloop on their own.
- * - It prevents multiple xmpp classes from creating multiple internal threads (which would be resource costly).
- *
- * Please note:
- * This thread is designed to be used only if absolutely necessary.
- * That is, if you MUST use a class that doesn't yet support pure GCD.
- * If there is a GCD alternative, you should be using it instead.
- * For example, do NOT use NSTimer. Instead setup a GCD timer using a dispatch_source.
- **/
- - (NSThread *)xmppUtilityThread;
- - (NSRunLoop *)xmppUtilityRunLoop;
- @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 possible keys and values for the security settings are well documented.
- * Some possible keys are:
- * - kCFStreamSSLLevel
- * - kCFStreamSSLAllowsExpiredCertificates
- * - kCFStreamSSLAllowsExpiredRoots
- * - kCFStreamSSLAllowsAnyRoot
- * - kCFStreamSSLValidatesCertificateChain
- * - kCFStreamSSLPeerName
- * - kCFStreamSSLCertificates
- *
- * Please refer to Apple's documentation for associated values, as well as other possible keys.
- *
- * The dictionary of settings is what will be passed to the startTLS method of ther underlying AsyncSocket.
- * The AsyncSocket header file also contains a discussion of 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.
- **/
- - (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:(NSMutableDictionary *)settings;
- /**
- * 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;
- /**
- * 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;
- /**
- * 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.
- **/
- - (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 disconnect method is called.
- * It may be used to determine if a disconnection was purposeful, or due to an error.
- **/
- - (void)xmppStreamWasToldToDisconnect:(XMPPStream *)sender;
- /**
- * This methods 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.
- **/
- - (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;
- @end