PageRenderTime 110ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/External/XMPPFramework/Core/XMPPStream.h

https://gitlab.com/intelij/ChattAR-ios
C Header | 981 lines | 152 code | 105 blank | 724 comment | 0 complexity | f4314c1c39f9617b2f3ff7742baac8c1 MD5 | raw file
  1. #import <Foundation/Foundation.h>
  2. #import "XMPPSASLAuthentication.h"
  3. #import "GCDAsyncSocket.h"
  4. #import "GCDMulticastDelegate.h"
  5. #if TARGET_OS_IPHONE
  6. #import "DDXML.h"
  7. #endif
  8. @class XMPPSRVResolver;
  9. @class XMPPParser;
  10. @class XMPPJID;
  11. @class XMPPIQ;
  12. @class XMPPMessage;
  13. @class XMPPPresence;
  14. @class XMPPModule;
  15. @class XMPPElementReceipt;
  16. @protocol XMPPStreamDelegate;
  17. #if TARGET_OS_IPHONE
  18. #define MIN_KEEPALIVE_INTERVAL 20.0 // 20 Seconds
  19. #define DEFAULT_KEEPALIVE_INTERVAL 120.0 // 2 Minutes
  20. #else
  21. #define MIN_KEEPALIVE_INTERVAL 10.0 // 10 Seconds
  22. #define DEFAULT_KEEPALIVE_INTERVAL 300.0 // 5 Minutes
  23. #endif
  24. extern NSString *const XMPPStreamErrorDomain;
  25. enum XMPPStreamErrorCode
  26. {
  27. XMPPStreamInvalidType, // Attempting to access P2P methods in a non-P2P stream, or vice-versa
  28. XMPPStreamInvalidState, // Invalid state for requested action, such as connect when already connected
  29. XMPPStreamInvalidProperty, // Missing a required property, such as myJID
  30. XMPPStreamInvalidParameter, // Invalid parameter, such as a nil JID
  31. XMPPStreamUnsupportedAction, // The server doesn't support the requested action
  32. };
  33. typedef enum XMPPStreamErrorCode XMPPStreamErrorCode;
  34. extern const NSTimeInterval XMPPStreamTimeoutNone;
  35. @interface XMPPStream : NSObject <GCDAsyncSocketDelegate>
  36. /**
  37. * Standard XMPP initialization.
  38. * The stream is a standard client to server connection.
  39. *
  40. * P2P streams using XEP-0174 are also supported.
  41. * See the P2P section below.
  42. **/
  43. - (id)init;
  44. /**
  45. * Peer to Peer XMPP initialization.
  46. * The stream is a direct client to client connection as outlined in XEP-0174.
  47. **/
  48. - (id)initP2PFrom:(XMPPJID *)myJID;
  49. /**
  50. * XMPPStream uses a multicast delegate.
  51. * This allows one to add multiple delegates to a single XMPPStream instance,
  52. * which makes it easier to separate various components and extensions.
  53. *
  54. * For example, if you were implementing two different custom extensions on top of XMPP,
  55. * you could put them in separate classes, and simply add each as a delegate.
  56. **/
  57. - (void)addDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
  58. - (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
  59. - (void)removeDelegate:(id)delegate;
  60. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  61. #pragma mark Properties
  62. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. /**
  64. * The server's hostname that should be used to make the TCP connection.
  65. * This may be a domain name (e.g. "deusty.com") or an IP address (e.g. "70.85.193.226").
  66. *
  67. * Note that this may be different from the virtual xmpp hostname.
  68. * Just as HTTP servers can support mulitple virtual hosts from a single server, so too can xmpp servers.
  69. * A prime example is google via google apps.
  70. *
  71. * For example, say you own the domain "mydomain.com".
  72. * If you go to mydomain.com in a web browser,
  73. * you are directed to your apache server running on your webserver somewhere in the cloud.
  74. * But you use google apps for your email and xmpp needs.
  75. * So if somebody sends you an email, it actually goes to google's servers, where you later access it from.
  76. * Similarly, you connect to google's servers to sign into xmpp.
  77. *
  78. * In the example above, your hostname is "talk.google.com" and your JID is "me@mydomain.com".
  79. *
  80. * This hostName property is optional.
  81. * If you do not set the hostName, then the framework will follow the xmpp specification using jid's domain.
  82. * That is, it first do an SRV lookup (as specified in the xmpp RFC).
  83. * If that fails, it will fall back to simply attempting to connect to the jid's domain.
  84. **/
  85. @property (readwrite, copy) NSString *hostName;
  86. /**
  87. * The port the xmpp server is running on.
  88. * If you do not explicitly set the port, the default port will be used.
  89. * If you set the port to zero, the default port will be used.
  90. *
  91. * The default port is 5222.
  92. **/
  93. @property (readwrite, assign) UInt16 hostPort;
  94. /**
  95. * Start TLS is used if the server supports it, regardless of wether it is required or not.
  96. *
  97. * The default is NO
  98. **/
  99. @property (readwrite, assign) BOOL autoStartTLS;
  100. /**
  101. * The JID of the user.
  102. *
  103. * This value is required, and is used in many parts of the underlying implementation.
  104. * When connecting, the domain of the JID is used to properly specify the correct xmpp virtual host.
  105. * It is used during registration to supply the username of the user to create an account for.
  106. * It is used during authentication to supply the username of the user to authenticate with.
  107. * And the resource may be used post-authentication during the required xmpp resource binding step.
  108. *
  109. * A proper JID is of the form user@domain/resource.
  110. * For example: robbiehanson@deusty.com/work
  111. *
  112. * The resource is optional, in the sense that if one is not supplied,
  113. * one will be automatically generated for you (either by us or by the server).
  114. *
  115. * Please note:
  116. * Resource collisions are handled in different ways depending on server configuration.
  117. *
  118. * For example:
  119. * You are signed in with user1@domain.com/home on your desktop.
  120. * Then you attempt to sign in with user1@domain.com/home on your laptop.
  121. *
  122. * The server could possibly:
  123. * - Reject the resource request for the laptop.
  124. * - Accept the resource request for the laptop, and immediately disconnect the desktop.
  125. * - Automatically assign the laptop another resource without a conflict.
  126. *
  127. * For this reason, you may wish to check the myJID variable after the stream has been connected,
  128. * just in case the resource was changed by the server.
  129. **/
  130. @property (readwrite, copy) XMPPJID *myJID;
  131. /**
  132. * Only used in P2P streams.
  133. **/
  134. @property (strong, readonly) XMPPJID *remoteJID;
  135. /**
  136. * Many routers will teardown a socket mapping if there is no activity on the socket.
  137. * For this reason, the xmpp stream supports sending keep-alive data.
  138. * This is simply whitespace, which is ignored by the xmpp protocol.
  139. *
  140. * Keep-alive data is only sent in the absence of any other data being sent/received.
  141. *
  142. * The default value is defined in DEFAULT_KEEPALIVE_INTERVAL.
  143. * The minimum value is defined in MIN_KEEPALIVE_INTERVAL.
  144. *
  145. * To disable keep-alive, set the interval to zero (or any non-positive number).
  146. *
  147. * The keep-alive timer (if enabled) fires every (keepAliveInterval / 4) seconds.
  148. * Upon firing it checks when data was last sent/received,
  149. * and sends keep-alive data if the elapsed time has exceeded the keepAliveInterval.
  150. * Thus the effective resolution of the keepalive timer is based on the interval.
  151. *
  152. * @see keepAliveWhitespaceCharacter
  153. **/
  154. @property (readwrite, assign) NSTimeInterval keepAliveInterval;
  155. /**
  156. * The keep-alive mechanism sends whitespace which is ignored by the xmpp protocol.
  157. * The default whitespace character is a space (' ').
  158. *
  159. * This can be changed, for whatever reason, to another whitespace character.
  160. * Valid whitespace characters are space(' '), tab('\t') and newline('\n').
  161. *
  162. * If you attempt to set the character to any non-whitespace character, the attempt is ignored.
  163. *
  164. * @see keepAliveInterval
  165. **/
  166. @property (readwrite, assign) char keepAliveWhitespaceCharacter;
  167. /**
  168. * Represents the last sent presence element concerning the presence of myJID on the server.
  169. * In other words, it represents the presence as others see us.
  170. *
  171. * This excludes presence elements sent concerning subscriptions, MUC rooms, etc.
  172. *
  173. * @see resendMyPresence
  174. **/
  175. @property (strong, readonly) XMPPPresence *myPresence;
  176. /**
  177. * Returns the total number of bytes bytes sent/received by the xmpp stream.
  178. *
  179. * By default this is the byte count since the xmpp stream object has been created.
  180. * If the stream has connected/disconnected/reconnected multiple times,
  181. * the count will be the summation of all connections.
  182. *
  183. * The functionality may optionaly be changed to count only the current socket connection.
  184. * See the resetByteCountPerConnection property.
  185. **/
  186. @property (readonly) UInt64 numberOfBytesSent;
  187. @property (readonly) UInt64 numberOfBytesReceived;
  188. /**
  189. * Affects the funtionality of the byte counter.
  190. *
  191. * The default value is NO.
  192. *
  193. * If set to YES, the byte count will be reset just prior to a new connection (in the connect methods).
  194. **/
  195. @property (readwrite, assign) BOOL resetByteCountPerConnection;
  196. /**
  197. * The tag property allows you to associate user defined information with the stream.
  198. * Tag values are not used internally, and should not be used by xmpp modules.
  199. **/
  200. @property (readwrite, strong) id tag;
  201. #if TARGET_OS_IPHONE
  202. /**
  203. * If set, the kCFStreamNetworkServiceTypeVoIP flags will be set on the underlying CFRead/Write streams.
  204. *
  205. * The default value is NO.
  206. **/
  207. @property (readwrite, assign) BOOL enableBackgroundingOnSocket;
  208. #endif
  209. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  210. #pragma mark State
  211. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  212. /**
  213. * Returns YES if the connection is closed, and thus no stream is open.
  214. * If the stream is neither disconnected, nor connected, then a connection is currently being established.
  215. **/
  216. - (BOOL)isDisconnected;
  217. /**
  218. * Returns YES is the connection is currently connecting
  219. **/
  220. - (BOOL)isConnecting;
  221. /**
  222. * Returns YES if the connection is open, and the stream has been properly established.
  223. * If the stream is neither disconnected, nor connected, then a connection is currently being established.
  224. *
  225. * If this method returns YES, then it is ready for you to start sending and receiving elements.
  226. **/
  227. - (BOOL)isConnected;
  228. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  229. #pragma mark Connect & Disconnect
  230. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  231. /**
  232. * Connects to the configured hostName on the configured hostPort.
  233. * The timeout is optional. To not time out use XMPPStreamTimeoutNone.
  234. * If the hostName or myJID are not set, this method will return NO and set the error parameter.
  235. **/
  236. - (BOOL)connectWithTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr;
  237. /**
  238. * THIS IS DEPRECATED BY THE XMPP SPECIFICATION.
  239. *
  240. * The xmpp specification outlines the proper use of SSL/TLS by negotiating
  241. * the startTLS upgrade within the stream negotiation.
  242. * This method exists for those ancient servers that still require the connection to be secured prematurely.
  243. * The timeout is optional. To not time out use XMPPStreamTimeoutNone.
  244. *
  245. * Note: Such servers generally use port 5223 for this, which you will need to set.
  246. **/
  247. - (BOOL)oldSchoolSecureConnectWithTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr;
  248. /**
  249. * Starts a P2P connection to the given user and given address.
  250. * The timeout is optional. To not time out use XMPPStreamTimeoutNone.
  251. * This method only works with XMPPStream objects created using the initP2P method.
  252. *
  253. * The given address is specified as a sockaddr structure wrapped in a NSData object.
  254. * For example, a NSData object returned from NSNetservice's addresses method.
  255. **/
  256. - (BOOL)connectTo:(XMPPJID *)remoteJID withAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr;
  257. /**
  258. * Starts a P2P connection with the given accepted socket.
  259. * This method only works with XMPPStream objects created using the initP2P method.
  260. *
  261. * The given socket should be a socket that has already been accepted.
  262. * The remoteJID will be extracted from the opening stream negotiation.
  263. **/
  264. - (BOOL)connectP2PWithSocket:(GCDAsyncSocket *)acceptedSocket error:(NSError **)errPtr;
  265. /**
  266. * Disconnects from the remote host by closing the underlying TCP socket connection.
  267. * The terminating </stream:stream> element is not sent to the server.
  268. *
  269. * This method is synchronous.
  270. * Meaning that the disconnect will happen immediately, even if there are pending elements yet to be sent.
  271. *
  272. * The xmppStreamDidDisconnect:withError: delegate method will immediately be dispatched onto the delegate queue.
  273. **/
  274. - (void)disconnect;
  275. /**
  276. * Disconnects from the remote host by sending the terminating </stream:stream> element,
  277. * and then closing the underlying TCP socket connection.
  278. *
  279. * This method is asynchronous.
  280. * The disconnect will happen after all pending elements have been sent.
  281. * Attempting to send elements after this method has been called will not work (the elements won't get sent).
  282. **/
  283. - (void)disconnectAfterSending;
  284. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  285. #pragma mark Security
  286. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  287. /**
  288. * Returns YES if SSL/TLS was used to establish a connection to the server.
  289. *
  290. * Some servers may require an "upgrade to TLS" in order to start communication,
  291. * so even if the connection was not explicitly secured, an ugrade to TLS may have occured.
  292. *
  293. * See also the xmppStream:willSecureWithSettings: delegate method.
  294. **/
  295. - (BOOL)isSecure;
  296. /**
  297. * Returns whether or not the server supports securing the connection via SSL/TLS.
  298. *
  299. * Some servers will actually require a secure connection,
  300. * in which case the stream will attempt to secure the connection during the opening process.
  301. *
  302. * If the connection has already been secured, this method may return NO.
  303. **/
  304. - (BOOL)supportsStartTLS;
  305. /**
  306. * Attempts to secure the connection via SSL/TLS.
  307. *
  308. * This method is asynchronous.
  309. * The SSL/TLS handshake will occur in the background, and
  310. * the xmppStreamDidSecure: delegate method will be called after the TLS process has completed.
  311. *
  312. * This method returns immediately.
  313. * If the secure process was started, it will return YES.
  314. * If there was an issue while starting the security process,
  315. * this method will return NO and set the error parameter.
  316. *
  317. * The errPtr parameter is optional - you may pass nil.
  318. *
  319. * You may wish to configure the security settings via the xmppStream:willSecureWithSettings: delegate method.
  320. *
  321. * If the SSL/TLS handshake fails, the connection will be closed.
  322. * The reason for the error will be reported via the xmppStreamDidDisconnect:withError: delegate method.
  323. * The error parameter will be an NSError object, and may have an error domain of kCFStreamErrorDomainSSL.
  324. * The corresponding error code is documented in Apple's Security framework, in SecureTransport.h
  325. **/
  326. - (BOOL)secureConnection:(NSError **)errPtr;
  327. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  328. #pragma mark Registration
  329. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  330. /**
  331. * In Band Registration.
  332. * Creating a user account on the xmpp server within the xmpp protocol.
  333. *
  334. * The registerWithElements:error: method is asynchronous.
  335. * It will return immediately, and the delegate methods are used to determine success.
  336. * See the xmppStreamDidRegister: and xmppStream:didNotRegister: methods.
  337. *
  338. * If there is something immediately wrong, such as the stream is not connected,
  339. * this method will return NO and set the error.
  340. *
  341. * The errPtr parameter is optional - you may pass nil.
  342. *
  343. * registerWithPassword:error: is a convience method for creating an account using the given username and password.
  344. *
  345. * Security Note:
  346. * The password will be sent in the clear unless the stream has been secured.
  347. **/
  348. - (BOOL)supportsInBandRegistration;
  349. - (BOOL)registerWithElements:(NSArray *)elements error:(NSError **)errPtr;
  350. - (BOOL)registerWithPassword:(NSString *)password error:(NSError **)errPtr;
  351. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  352. #pragma mark Authentication
  353. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  354. /**
  355. * Returns the server's list of supported authentication mechanisms.
  356. * Each item in the array will be of type NSString.
  357. *
  358. * For example, if the server supplied this stanza within it's reported stream:features:
  359. *
  360. * <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
  361. * <mechanism>DIGEST-MD5</mechanism>
  362. * <mechanism>PLAIN</mechanism>
  363. * </mechanisms>
  364. *
  365. * Then this method would return [@"DIGEST-MD5", @"PLAIN"].
  366. **/
  367. - (NSArray *)supportedAuthenticationMechanisms;
  368. /**
  369. * Returns whether or not the given authentication mechanism name was specified in the
  370. * server's list of supported authentication mechanisms.
  371. *
  372. * Note: The authentication classes often provide a category on XMPPStream, adding useful methods.
  373. *
  374. * @see XMPPPlainAuthentication - supportsPlainAuthentication
  375. * @see XMPPDigestMD5Authentication - supportsDigestMD5Authentication
  376. * @see XMPPXFacebookPlatformAuthentication - supportsXFacebookPlatformAuthentication
  377. * @see XMPPDeprecatedPlainAuthentication - supportsDeprecatedPlainAuthentication
  378. * @see XMPPDeprecatedDigestAuthentication - supportsDeprecatedDigestAuthentication
  379. **/
  380. - (BOOL)supportsAuthenticationMechanism:(NSString *)mechanism;
  381. /**
  382. * This is the root authentication method.
  383. * All other authentication methods go through this one.
  384. *
  385. * This method attempts to start the authentication process given the auth instance.
  386. * That is, this method will invoke start: on the given auth instance.
  387. * If it returns YES, then the stream will enter into authentication mode.
  388. * It will then continually invoke the handleAuth: method on the given instance until authentication is complete.
  389. *
  390. * This method is asynchronous.
  391. *
  392. * If there is something immediately wrong, such as the stream is not connected,
  393. * the method will return NO and set the error.
  394. * Otherwise the delegate callbacks are used to communicate auth success or failure.
  395. *
  396. * @see xmppStreamDidAuthenticate:
  397. * @see xmppStream:didNotAuthenticate:
  398. *
  399. * @see authenticateWithPassword:error:
  400. *
  401. * Note: The security process is abstracted in order to provide flexibility,
  402. * and allow developers to easily implement their own custom authentication protocols.
  403. * The authentication classes often provide a category on XMPPStream, adding useful methods.
  404. *
  405. * @see XMPPXFacebookPlatformAuthentication - authenticateWithFacebookAccessToken:error:
  406. **/
  407. - (BOOL)authenticate:(id <XMPPSASLAuthentication>)auth error:(NSError **)errPtr;
  408. /**
  409. * This method applies to standard password authentication schemes only.
  410. * This is NOT the primary authentication method.
  411. *
  412. * @see authenticate:error:
  413. *
  414. * This method exists for backwards compatibility, and may disappear in future versions.
  415. **/
  416. - (BOOL)authenticateWithPassword:(NSString *)password error:(NSError **)errPtr;
  417. /**
  418. * Returns whether or not the xmpp stream is currently authenticating with the XMPP Server.
  419. **/
  420. - (BOOL)isAuthenticating;
  421. /**
  422. * Returns whether or not the xmpp stream has successfully authenticated with the server.
  423. **/
  424. - (BOOL)isAuthenticated;
  425. /**
  426. * Returns the date when the xmpp stream successfully authenticated with the server.
  427. **/
  428. - (NSDate *)authenticationDate;
  429. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  430. #pragma mark Compression
  431. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  432. /**
  433. * Returns the server's list of supported compression methods in accordance to XEP-0138: Stream Compression
  434. * Each item in the array will be of type NSString.
  435. *
  436. * For example, if the server supplied this stanza within it's reported stream:features:
  437. *
  438. * <compression xmlns='http://jabber.org/features/compress'>
  439. * <method>zlib</method>
  440. * <method>lzw</method>
  441. * </compression>
  442. *
  443. * Then this method would return [@"zlib", @"lzw"].
  444. **/
  445. - (NSArray *)supportedCompressionMethods;
  446. /**
  447. * Returns whether or not the given compression method name was specified in the
  448. * server's list of supported compression methods.
  449. *
  450. * Note: The XMPPStream doesn't currently support any compression methods
  451. **/
  452. - (BOOL)supportsCompressionMethod:(NSString *)compressionMethod;
  453. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  454. #pragma mark Server Info
  455. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  456. /**
  457. * This method will return the root element of the document.
  458. * This element contains the opening <stream:stream/> and <stream:features/> tags received from the server.
  459. *
  460. * If multiple <stream:features/> have been received during the course of stream negotiation,
  461. * the root element contains only the most recent (current) version.
  462. *
  463. * Note: The rootElement is "empty", in-so-far as it does not contain all the XML elements the stream has
  464. * received during it's connection. This is done for performance reasons and for the obvious benefit
  465. * of being more memory efficient.
  466. **/
  467. - (NSXMLElement *)rootElement;
  468. /**
  469. * Returns the version attribute from the servers's <stream:stream/> element.
  470. * This should be at least 1.0 to be RFC 3920 compliant.
  471. * If no version number was set, the server is not RFC compliant, and 0 is returned.
  472. **/
  473. - (float)serverXmppStreamVersionNumber;
  474. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  475. #pragma mark Sending
  476. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  477. /**
  478. * Sends the given XML element.
  479. * If the stream is not yet connected, this method does nothing.
  480. **/
  481. - (void)sendElement:(NSXMLElement *)element;
  482. /**
  483. * Just like the sendElement: method above,
  484. * but allows you to receive a receipt that can later be used to verify the element has been sent.
  485. *
  486. * If you later want to check to see if the element has been sent:
  487. *
  488. * if ([receipt wait:0]) {
  489. * // Element has been sent
  490. * }
  491. *
  492. * If you later want to wait until the element has been sent:
  493. *
  494. * if ([receipt wait:-1]) {
  495. * // Element was sent
  496. * } else {
  497. * // Element failed to send due to disconnection
  498. * }
  499. *
  500. * It is important to understand what it means when [receipt wait:timeout] returns YES.
  501. * It does NOT mean the server has received the element.
  502. * It only means the data has been queued for sending in the underlying OS socket buffer.
  503. *
  504. * So at this point the OS will do everything in its capacity to send the data to the server,
  505. * which generally means the server will eventually receive the data.
  506. * Unless, of course, something horrible happens such as a network failure,
  507. * or a system crash, or the server crashes, etc.
  508. *
  509. * Even if you close the xmpp stream after this point, the OS will still do everything it can to send the data.
  510. **/
  511. - (void)sendElement:(NSXMLElement *)element andGetReceipt:(XMPPElementReceipt **)receiptPtr;
  512. /**
  513. * Fetches and resends the myPresence element (if available) in a single atomic operation.
  514. *
  515. * There are various xmpp extensions that hook into the xmpp stream and append information to outgoing presence stanzas.
  516. * For example, the XMPPCapabilities module automatically appends capabilities information (as a hash).
  517. * When these modules need to update/change their appended information,
  518. * they should use this method to do so.
  519. *
  520. * The alternative is to fetch the myPresence element, and resend it manually using the sendElement method.
  521. * However, that is 2 seperate operations, and the user, may send a different presence element inbetween.
  522. * Using this method guarantees everything is done as an atomic operation.
  523. **/
  524. - (void)resendMyPresence;
  525. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  526. #pragma mark Module Plug-In System
  527. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  528. /**
  529. * The XMPPModule class automatically invokes these methods when it is activated/deactivated.
  530. *
  531. * The registerModule method registers the module with the xmppStream.
  532. * If there are any other modules that have requested to be automatically added as delegates to modules of this type,
  533. * then those modules are automatically added as delegates during the asynchronous execution of this method.
  534. *
  535. * The registerModule method is asynchronous.
  536. *
  537. * The unregisterModule method unregisters the module with the xmppStream,
  538. * and automatically removes it as a delegate of any other module.
  539. *
  540. * The unregisterModule method is fully synchronous.
  541. * That is, after this method returns, the module will not be scheduled in any more delegate calls from other modules.
  542. * However, if the module was already scheduled in an existing asynchronous delegate call from another module,
  543. * the scheduled delegate invocation remains queued and will fire in the near future.
  544. * Since the delegate invocation is already queued,
  545. * the module's retainCount has been incremented,
  546. * and the module will not be deallocated until after the delegate invocation has fired.
  547. **/
  548. - (void)registerModule:(XMPPModule *)module;
  549. - (void)unregisterModule:(XMPPModule *)module;
  550. /**
  551. * Automatically registers the given delegate with all current and future registered modules of the given class.
  552. *
  553. * That is, the given delegate will be added to the delegate list ([module addDelegate:delegate delegateQueue:dq]) to
  554. * all current and future registered modules that respond YES to [module isKindOfClass:aClass].
  555. *
  556. * This method is used by modules to automatically integrate with other modules.
  557. * For example, a module may auto-add itself as a delegate to XMPPCapabilities
  558. * so that it can broadcast its implemented features.
  559. *
  560. * This may also be useful to clients, for example, to add a delegate to instances of something like XMPPChatRoom,
  561. * where there may be multiple instances of the module that get created during the course of an xmpp session.
  562. *
  563. * If you auto register on multiple queues, you can remove all registrations with a single
  564. * call to removeAutoDelegate::: by passing NULL as the 'dq' parameter.
  565. *
  566. * If you auto register for multiple classes, you can remove all registrations with a single
  567. * call to removeAutoDelegate::: by passing nil as the 'aClass' parameter.
  568. **/
  569. - (void)autoAddDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue toModulesOfClass:(Class)aClass;
  570. - (void)removeAutoDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue fromModulesOfClass:(Class)aClass;
  571. /**
  572. * Allows for enumeration of the currently registered modules.
  573. *
  574. * This may be useful if the stream needs to be queried for modules of a particular type.
  575. **/
  576. - (void)enumerateModulesWithBlock:(void (^)(XMPPModule *module, NSUInteger idx, BOOL *stop))block;
  577. /**
  578. * Allows for enumeration of the currently registered modules that are a kind of Class.
  579. * idx is in relation to all modules not just those of the given class.
  580. **/
  581. - (void)enumerateModulesOfClass:(Class)aClass withBlock:(void (^)(XMPPModule *module, NSUInteger idx, BOOL *stop))block;
  582. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  583. #pragma mark Utilities
  584. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  585. /**
  586. * Generates and returns a new autoreleased UUID.
  587. * UUIDs (Universally Unique Identifiers) may also be known as GUIDs (Globally Unique Identifiers).
  588. *
  589. * The UUID is generated using the CFUUID library, which generates a unique 128 bit value.
  590. * The uuid is then translated into a string using the standard format for UUIDs:
  591. * "68753A44-4D6F-1226-9C60-0050E4C00067"
  592. *
  593. * This method is most commonly used to generate a unique id value for an xmpp element.
  594. **/
  595. + (NSString *)generateUUID;
  596. - (NSString *)generateUUID;
  597. /**
  598. * The XMPP Framework is designed to be entirely GCD based.
  599. * However, there are various utility classes provided by Apple that are still dependent upon a thread/runloop model.
  600. * For example, monitoring a network for changes related to connectivity requires we register a runloop-based delegate.
  601. * Thus XMPPStream creates a dedicated thread/runloop for any xmpp classes that may need it.
  602. * This provides multiple benefits:
  603. *
  604. * - Development is simplified for those transitioning from previous thread/runloop versions.
  605. * - Development is simplified for those who rely on utility classes that don't yet support pure GCD,
  606. * as they don't have to setup and maintain a thread/runloop on their own.
  607. * - It prevents multiple xmpp classes from creating multiple internal threads (which would be resource costly).
  608. *
  609. * Please note:
  610. * This thread is designed to be used only if absolutely necessary.
  611. * That is, if you MUST use a class that doesn't yet support pure GCD.
  612. * If there is a GCD alternative, you should be using it instead.
  613. * For example, do NOT use NSTimer. Instead setup a GCD timer using a dispatch_source.
  614. **/
  615. - (NSThread *)xmppUtilityThread;
  616. - (NSRunLoop *)xmppUtilityRunLoop;
  617. @end
  618. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  619. #pragma mark -
  620. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  621. @interface XMPPElementReceipt : NSObject
  622. {
  623. uint32_t atomicFlags;
  624. dispatch_semaphore_t semaphore;
  625. }
  626. /**
  627. * Element receipts allow you to check to see if the element has been sent.
  628. * The timeout parameter allows you to do any of the following:
  629. *
  630. * - Do an instantaneous check (pass timeout == 0)
  631. * - Wait until the element has been sent (pass timeout < 0)
  632. * - Wait up to a certain amount of time (pass timeout > 0)
  633. *
  634. * It is important to understand what it means when [receipt wait:timeout] returns YES.
  635. * It does NOT mean the server has received the element.
  636. * It only means the data has been queued for sending in the underlying OS socket buffer.
  637. *
  638. * So at this point the OS will do everything in its capacity to send the data to the server,
  639. * which generally means the server will eventually receive the data.
  640. * Unless, of course, something horrible happens such as a network failure,
  641. * or a system crash, or the server crashes, etc.
  642. *
  643. * Even if you close the xmpp stream after this point, the OS will still do everything it can to send the data.
  644. **/
  645. - (BOOL)wait:(NSTimeInterval)timeout;
  646. @end
  647. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  648. #pragma mark -
  649. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  650. @protocol XMPPStreamDelegate
  651. @optional
  652. /**
  653. * This method is called before the stream begins the connection process.
  654. *
  655. * If developing an iOS app that runs in the background, this may be a good place to indicate
  656. * that this is a task that needs to continue running in the background.
  657. **/
  658. - (void)xmppStreamWillConnect:(XMPPStream *)sender;
  659. /**
  660. * This method is called after the tcp socket has connected to the remote host.
  661. * It may be used as a hook for various things, such as updating the UI or extracting the server's IP address.
  662. *
  663. * If developing an iOS app that runs in the background,
  664. * please use XMPPStream's enableBackgroundingOnSocket property as opposed to doing it directly on the socket here.
  665. **/
  666. - (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket;
  667. /**
  668. * This method is called after a TCP connection has been established with the server,
  669. * and the opening XML stream negotiation has started.
  670. **/
  671. - (void)xmppStreamDidStartNegotiation:(XMPPStream *)sender;
  672. /**
  673. * This method is called immediately prior to the stream being secured via TLS/SSL.
  674. * Note that this delegate may be called even if you do not explicitly invoke the startTLS method.
  675. * Servers have the option of requiring connections to be secured during the opening process.
  676. * If this is the case, the XMPPStream will automatically attempt to properly secure the connection.
  677. *
  678. * The possible keys and values for the security settings are well documented.
  679. * Some possible keys are:
  680. * - kCFStreamSSLLevel
  681. * - kCFStreamSSLAllowsExpiredCertificates
  682. * - kCFStreamSSLAllowsExpiredRoots
  683. * - kCFStreamSSLAllowsAnyRoot
  684. * - kCFStreamSSLValidatesCertificateChain
  685. * - kCFStreamSSLPeerName
  686. * - kCFStreamSSLCertificates
  687. *
  688. * Please refer to Apple's documentation for associated values, as well as other possible keys.
  689. *
  690. * The dictionary of settings is what will be passed to the startTLS method of ther underlying AsyncSocket.
  691. * The AsyncSocket header file also contains a discussion of the security consequences of various options.
  692. * It is recommended reading if you are planning on implementing this method.
  693. *
  694. * The dictionary of settings that are initially passed will be an empty dictionary.
  695. * If you choose not to implement this method, or simply do not edit the dictionary,
  696. * then the default settings will be used.
  697. * That is, the kCFStreamSSLPeerName will be set to the configured host name,
  698. * and the default security validation checks will be performed.
  699. *
  700. * This means that authentication will fail if the name on the X509 certificate of
  701. * the server does not match the value of the hostname for the xmpp stream.
  702. * It will also fail if the certificate is self-signed, or if it is expired, etc.
  703. *
  704. * These settings are most likely the right fit for most production environments,
  705. * but may need to be tweaked for development or testing,
  706. * where the development server may be using a self-signed certificate.
  707. **/
  708. - (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:(NSMutableDictionary *)settings;
  709. /**
  710. * This method is called after the stream has been secured via SSL/TLS.
  711. * This method may be called if the server required a secure connection during the opening process,
  712. * or if the secureConnection: method was manually invoked.
  713. **/
  714. - (void)xmppStreamDidSecure:(XMPPStream *)sender;
  715. /**
  716. * This method is called after the XML stream has been fully opened.
  717. * More precisely, this method is called after an opening <xml/> and <stream:stream/> tag have been sent and received,
  718. * and after the stream features have been received, and any required features have been fullfilled.
  719. * At this point it's safe to begin communication with the server.
  720. **/
  721. - (void)xmppStreamDidConnect:(XMPPStream *)sender;
  722. /**
  723. * This method is called after registration of a new user has successfully finished.
  724. * If registration fails for some reason, the xmppStream:didNotRegister: method will be called instead.
  725. **/
  726. - (void)xmppStreamDidRegister:(XMPPStream *)sender;
  727. /**
  728. * This method is called if registration fails.
  729. **/
  730. - (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error;
  731. /**
  732. * This method is called after authentication has successfully finished.
  733. * If authentication fails for some reason, the xmppStream:didNotAuthenticate: method will be called instead.
  734. **/
  735. - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender;
  736. /**
  737. * This method is called if authentication fails.
  738. **/
  739. - (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error;
  740. /**
  741. * This method is called if the XMPP server doesn't allow our resource of choice
  742. * because it conflicts with an existing resource.
  743. *
  744. * Return an alternative resource or return nil to let the server automatically pick a resource for us.
  745. **/
  746. - (NSString *)xmppStream:(XMPPStream *)sender alternativeResourceForConflictingResource:(NSString *)conflictingResource;
  747. /**
  748. * These methods are called before their respective XML elements are broadcast as received to the rest of the stack.
  749. * These methods can be used to modify elements on the fly.
  750. * (E.g. perform custom decryption so the rest of the stack sees readable text.)
  751. *
  752. * You may also filter incoming elements by returning nil.
  753. *
  754. * When implementing these methods to modify the element, you do not need to copy the given element.
  755. * You can simply edit the given element, and return it.
  756. * The reason these methods return an element, instead of void, is to allow filtering.
  757. *
  758. * Concerning thread-safety, delegates implementing the method are invoked one-at-a-time to
  759. * allow thread-safe modification of the given elements.
  760. *
  761. * You should NOT implement these methods unless you have good reason to do so.
  762. * For general processing and notification of received elements, please use xmppStream:didReceiveX: methods.
  763. *
  764. * @see xmppStream:didReceiveIQ:
  765. * @see xmppStream:didReceiveMessage:
  766. * @see xmppStream:didReceivePresence:
  767. **/
  768. - (XMPPIQ *)xmppStream:(XMPPStream *)sender willReceiveIQ:(XMPPIQ *)iq;
  769. - (XMPPMessage *)xmppStream:(XMPPStream *)sender willReceiveMessage:(XMPPMessage *)message;
  770. - (XMPPPresence *)xmppStream:(XMPPStream *)sender willReceivePresence:(XMPPPresence *)presence;
  771. /**
  772. * These methods are called after their respective XML elements are received on the stream.
  773. *
  774. * In the case of an IQ, the delegate method should return YES if it has or will respond to the given IQ.
  775. * If the IQ is of type 'get' or 'set', and no delegates respond to the IQ,
  776. * then xmpp stream will automatically send an error response.
  777. *
  778. * Concerning thread-safety, delegates shouldn't modify the given elements.
  779. * As documented in NSXML / KissXML, elements are read-access thread-safe, but write-access thread-unsafe.
  780. * If you have need to modify an element for any reason,
  781. * you should copy the element first, and then modify and use the copy.
  782. **/
  783. - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq;
  784. - (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message;
  785. - (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence;
  786. /**
  787. * This method is called if an XMPP error is received.
  788. * In other words, a <stream:error/>.
  789. *
  790. * However, this method may also be called for any unrecognized xml stanzas.
  791. *
  792. * Note that standard errors (<iq type='error'/> for example) are delivered normally,
  793. * via the other didReceive...: methods.
  794. **/
  795. - (void)xmppStream:(XMPPStream *)sender didReceiveError:(NSXMLElement *)error;
  796. /**
  797. * These methods are called before their respective XML elements are sent over the stream.
  798. * These methods can be used to modify outgoing elements on the fly.
  799. * (E.g. add standard information for custom protocols.)
  800. *
  801. * You may also filter outgoing elements by returning nil.
  802. *
  803. * When implementing these methods to modify the element, you do not need to copy the given element.
  804. * You can simply edit the given element, and return it.
  805. * The reason these methods return an element, instead of void, is to allow filtering.
  806. *
  807. * Concerning thread-safety, delegates implementing the method are invoked one-at-a-time to
  808. * allow thread-safe modification of the given elements.
  809. *
  810. * You should NOT implement these methods unless you have good reason to do so.
  811. * For general processing and notification of sent elements, please use xmppStream:didSendX: methods.
  812. *
  813. * @see xmppStream:didSendIQ:
  814. * @see xmppStream:didSendMessage:
  815. * @see xmppStream:didSendPresence:
  816. **/
  817. - (XMPPIQ *)xmppStream:(XMPPStream *)sender willSendIQ:(XMPPIQ *)iq;
  818. - (XMPPMessage *)xmppStream:(XMPPStream *)sender willSendMessage:(XMPPMessage *)message;
  819. - (XMPPPresence *)xmppStream:(XMPPStream *)sender willSendPresence:(XMPPPresence *)presence;
  820. /**
  821. * These methods are called after their respective XML elements are sent over the stream.
  822. * These methods may be used to listen for certain events (such as an unavailable presence having been sent),
  823. * or for general logging purposes. (E.g. a central history logging mechanism).
  824. **/
  825. - (void)xmppStream:(XMPPStream *)sender didSendIQ:(XMPPIQ *)iq;
  826. - (void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message;
  827. - (void)xmppStream:(XMPPStream *)sender didSendPresence:(XMPPPresence *)presence;
  828. /**
  829. * These methods are called after failing to send the respective XML elements over the stream.
  830. **/
  831. - (void)xmppStream:(XMPPStream *)sender didFailToSendIQ:(XMPPIQ *)iq error:(NSError *)error;
  832. - (void)xmppStream:(XMPPStream *)sender didFailToSendMessage:(XMPPMessage *)message error:(NSError *)error;
  833. - (void)xmppStream:(XMPPStream *)sender didFailToSendPresence:(XMPPPresence *)presence error:(NSError *)error;
  834. /**
  835. * This method is called if the disconnect method is called.
  836. * It may be used to determine if a disconnection was purposeful, or due to an error.
  837. **/
  838. - (void)xmppStreamWasToldToDisconnect:(XMPPStream *)sender;
  839. /**
  840. * This methods is called if the XMPP Stream's connect times out
  841. **/
  842. - (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender;
  843. /**
  844. * This method is called after the stream is closed.
  845. *
  846. * The given error parameter will be non-nil if the error was due to something outside the general xmpp realm.
  847. * Some examples:
  848. * - The TCP socket was unexpectedly disconnected.
  849. * - The SRV resolution of the domain failed.
  850. * - Error parsing xml sent from server.
  851. **/
  852. - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error;
  853. /**
  854. * This method is only used in P2P mode when the connectTo:withAddress: method was used.
  855. *
  856. * It allows the delegate to read the <stream:features/> element if/when they arrive.
  857. * Recall that the XEP specifies that <stream:features/> SHOULD be sent.
  858. **/
  859. - (void)xmppStream:(XMPPStream *)sender didReceiveP2PFeatures:(NSXMLElement *)streamFeatures;
  860. /**
  861. * This method is only used in P2P mode when the connectTo:withSocket: method was used.
  862. *
  863. * It allows the delegate to customize the <stream:features/> element,
  864. * adding any specific featues the delegate might support.
  865. **/
  866. - (void)xmppStream:(XMPPStream *)sender willSendP2PFeatures:(NSXMLElement *)streamFeatures;
  867. /**
  868. * These methods are called as xmpp modules are registered and unregistered with the stream.
  869. * This generally corresponds to xmpp modules being initailzed and deallocated.
  870. *
  871. * The methods may be useful, for example, if a more precise auto delegation mechanism is needed
  872. * than what is available with the autoAddDelegate:toModulesOfClass: method.
  873. **/
  874. - (void)xmppStream:(XMPPStream *)sender didRegisterModule:(id)module;
  875. - (void)xmppStream:(XMPPStream *)sender willUnregisterModule:(id)module;
  876. @end