XMPP(3)

本篇文章是整理以前在CSDN上所發(fā)表的文章荷科,更新文章內(nèi)容,更詳細(xì)地描述操作段只,以方便大家閱讀和理解。

本篇文章的內(nèi)容是一年前寫(xiě)的鉴扫,不代表到現(xiàn)在還可以正常使用赞枕,但是即使有版本更新,功能上還是一樣的坪创,還是具有參考價(jià)值的炕婶。當(dāng)然,對(duì)于筆者而言误堡,就是重新收拾收拾很久沒(méi)有使用過(guò)的知識(shí)了古话!如果您正在尋找XMPP方面的資料,我相信這里可以幫助到您锁施!

XMPPFramework結(jié)構(gòu)

在進(jìn)入下一步之前陪踩,先給大家講講XMPPFramework的目錄結(jié)構(gòu),以便新手們更容易讀懂文章悉抵。我們來(lái)看看下圖:

雖然這里有很多個(gè)目錄肩狂,但是我們?cè)陂_(kāi)發(fā)中基本只關(guān)心Core和Extensions這兩個(gè)目錄下的類(lèi)。各個(gè)目錄主要用來(lái)干嘛的姥饰?

Authentication:這一看名字就知道與授權(quán)驗(yàn)證相關(guān)的傻谁。

Categories:主要是一些擴(kuò)展,尤其是NSXMLElement+XMPP擴(kuò)展是必備的列粪。

Core:這里是XMPP的核心文件目錄审磁,我們最主要的目光還是要放在這個(gè)目錄上。

Extensions:這個(gè)目錄是XMPP的擴(kuò)展岂座,用于擴(kuò)展各種協(xié)議和各種獨(dú)立的功能态蒂,其下每個(gè)子目錄都是對(duì)應(yīng)的一個(gè)單獨(dú)的子功能。我們最常用到的功能有Reconnect费什、Roster钾恢、CoreDataStorage等。

Utilities:都是輔助類(lèi)鸳址,我們開(kāi)發(fā)者不用關(guān)心這里瘩蚪。

Vendor:這個(gè)目錄是XMPP所引用的第三方類(lèi)庫(kù),如CocoaAsyncSocket稿黍、KissXML等疹瘦,我們也不用關(guān)心這里。

閱讀到此闻察,對(duì)XMPPFramework的結(jié)構(gòu)有所了解了吧拱礁!

概念知識(shí)

登錄需要到賬號(hào)琢锋,而所謂的賬號(hào)其實(shí)就是用戶(hù)唯一標(biāo)識(shí)符(JID),在XMPP中使用XMPPJID類(lèi)來(lái)表示呢灶。那么吴超,用戶(hù)唯一標(biāo)識(shí)(JID)有什么組成?

JID一般由三部分構(gòu)成:用戶(hù)名鸯乃,域名和資源名鲸阻,格式為user@domain/resource,例如:test@example.com/Anthony缨睡。對(duì)應(yīng)于XMPPJID類(lèi)中的三個(gè)屬性u(píng)ser鸟悴、domain、resource奖年。

如果沒(méi)有設(shè)置主機(jī)名(HOST)细诸,則使用JID的域名(domain)作為主機(jī)名,而端口號(hào)是可選的陋守,默認(rèn)是5222震贵,一般也沒(méi)有必要改動(dòng)它。

XMPPStream類(lèi)

我們要與服務(wù)器連接水评,就必須通過(guò)XMPPStream類(lèi)了猩系,它提供了很多的API和屬性設(shè)置,通過(guò)socket來(lái)實(shí)現(xiàn)的中燥。我們看到Verdor目錄了嗎寇甸,包含了CocoaAsyncSocket這個(gè)非常有名的socket編程庫(kù)。XMPPStream類(lèi)還遵守并實(shí)現(xiàn)了GCDAsyncSocketDelegate代理疗涉,用于客戶(hù)端與服務(wù)器交互拿霉。

@interface XMPPStream : NSObject

當(dāng)我們創(chuàng)建XMPPStream對(duì)象后,我們需要設(shè)置代理咱扣,才能回調(diào)我們的代理方法友浸,這個(gè)是支持multicast delegate,也就是說(shuō)對(duì)于一個(gè)XMPPStream對(duì)象偏窝,可以設(shè)置多個(gè)代理對(duì)象,其中協(xié)議是XMPPStreamDelegate:

- (void)addDelegate:(id)delegatedelegateQueue:(dispatch_queue_t)delegateQueue;

而當(dāng)我們不希望某個(gè)XMPPStream對(duì)象繼續(xù)接收到代理回調(diào)時(shí)武学,我們通過(guò)這樣的方式來(lái)移除代理:

- (void)removeDelegate:(id)delegatedelegateQueue:(dispatch_queue_t)delegateQueue;

- (void)removeDelegate:(id)delegate;

接下來(lái)祭往,我們要設(shè)置主機(jī)和端口,通過(guò)設(shè)置這兩個(gè)屬性:

/**

* The server's hostname that should be used to make the TCP connection.

* 注釋太長(zhǎng)火窒,簡(jiǎn)單說(shuō)就是主機(jī)硼补。這個(gè)屬性是可選設(shè)置的,如果沒(méi)有設(shè)置主機(jī)熏矿,默認(rèn)會(huì)使用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;

XMPPStream有XMPPJID類(lèi)對(duì)象作為屬性已骇,標(biāo)識(shí)用戶(hù)离钝,因?yàn)槲覀兒罄m(xù)很多操作都需要到myJID:

@property (readwrite, copy) XMPPJID *myJID;

而管理用戶(hù)在線狀態(tài)的就交由XMPPPresence類(lèi)了,它同樣被作為XMPPStream的屬性褪储,組合到XMPPStream中卵渴,后續(xù)很多關(guān)于用戶(hù)的操作是需要到處理用戶(hù)狀態(tài)的:

/**

* 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;

XMPPStreamDelegate

這個(gè)協(xié)議是非常關(guān)鍵的,我們的很多主要操作都集中在這個(gè)協(xié)議的代理回調(diào)上鲤竹。它分為好幾種類(lèi)型的代理API浪读,比如授權(quán)的、注冊(cè)的辛藻、安全的等:

@protocol XMPPStreamDelegate

@optional

// 將要與服務(wù)器連接是回調(diào)

- (void)xmppStreamWillConnect:(XMPPStream *)sender;

// 當(dāng)tcp socket已經(jīng)與遠(yuǎn)程主機(jī)連接上時(shí)會(huì)回調(diào)此代理方法

// 若App要求在后臺(tái)運(yùn)行碘橘,需要設(shè)置XMPPStream's enableBackgroundingOnSocket屬性

- (void)xmppStream:(XMPPStream *)sendersocketDidConnect:(GCDAsyncSocket *)socket;

// 當(dāng)TCP與服務(wù)器建立連接后會(huì)回調(diào)此代理方法

- (void)xmppStreamDidStartNegotiation:(XMPPStream *)sender;

// TLS傳輸層協(xié)議在將要驗(yàn)證安全設(shè)置時(shí)會(huì)回調(diào)

// 參數(shù)settings會(huì)被傳到startTLS

// 此方法可以不實(shí)現(xiàn)的,若選擇實(shí)現(xiàn)它吱肌,可以可以在

// 若服務(wù)端使用自簽名的證書(shū)痘拆,需要在settings中添加GCDAsyncSocketManuallyEvaluateTrust=YES

//

- (void)xmppStream:(XMPPStream *)senderwillSecureWithSettings:(NSMutableDictionary *)settings;

// 上面的方法執(zhí)行后,下一步就會(huì)執(zhí)行這個(gè)代理回調(diào)

// 用于在TCP握手時(shí)手動(dòng)驗(yàn)證是否受信任

- (void)xmppStream:(XMPPStream *)senderdidReceiveTrust:(SecTrustRef)trust

completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler;

// 當(dāng)stream通過(guò)了SSL/TLS的安全驗(yàn)證時(shí)氮墨,會(huì)回調(diào)此代理方法

- (void)xmppStreamDidSecure:(XMPPStream *)sender;

// 當(dāng)XML流已經(jīng)完全打開(kāi)時(shí)(也就是與服務(wù)器的連接完成時(shí))會(huì)回調(diào)此代理方法纺蛆。此時(shí)可以安全地與服務(wù)器通信了。

- (void)xmppStreamDidConnect:(XMPPStream *)sender;

// 注冊(cè)新用戶(hù)成功時(shí)的回調(diào)

- (void)xmppStreamDidRegister:(XMPPStream *)sender;

// 注冊(cè)新用戶(hù)失敗時(shí)的回調(diào)

- (void)xmppStream:(XMPPStream *)senderdidNotRegister:(NSXMLElement *)error;

// 授權(quán)通過(guò)時(shí)的回調(diào)勇边,也就是登錄成功的回調(diào)

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender;

// 授權(quán)失敗時(shí)的回調(diào)犹撒,也就是登錄失敗時(shí)的回調(diào)

- (void)xmppStream:(XMPPStream *)senderdidNotAuthenticate:(NSXMLElement *)error;

// 將要綁定JID resource時(shí)的回調(diào),這是授權(quán)程序的標(biāo)準(zhǔn)部分粒褒,當(dāng)驗(yàn)證JID用戶(hù)名通過(guò)時(shí)识颊,下一步就驗(yàn)證resource。若使用標(biāo)準(zhǔn)綁定處理奕坟,return nil或者不要實(shí)現(xiàn)此方法

- (id )xmppStreamWillBind:(XMPPStream *)sender;

// 如果服務(wù)器出現(xiàn)resouce沖突而導(dǎo)致不允許resource選擇時(shí)祥款,會(huì)回調(diào)此代理方法。返回指定的resource或者返回nil讓服務(wù)器自動(dòng)幫助我們來(lái)選擇月杉。一般不用實(shí)現(xiàn)它刃跛。

- (NSString *)xmppStream:(XMPPStream *)senderalternativeResourceForConflictingResource:(NSString *)conflictingResource;

// 將要發(fā)送IQ(消息查詢(xún))時(shí)的回調(diào)

- (XMPPIQ *)xmppStream:(XMPPStream *)senderwillReceiveIQ:(XMPPIQ *)iq;

// 將要接收到消息時(shí)的回調(diào)

- (XMPPMessage *)xmppStream:(XMPPStream *)senderwillReceiveMessage:(XMPPMessage *)message;

// 將要接收到用戶(hù)在線狀態(tài)時(shí)的回調(diào)

- (XMPPPresence *)xmppStream:(XMPPStream *)senderwillReceivePresence:(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.

**/

// 當(dāng)xmppStream:willReceiveX:(也就是前面這三個(gè)API回調(diào)后),過(guò)濾了stanza苛萎,會(huì)回調(diào)此代理方法桨昙。

// 通過(guò)實(shí)現(xiàn)此代理方法,可以知道被過(guò)濾的原因腌歉,有一定的幫助蛙酪。

- (void)xmppStreamDidFilterStanza:(XMPPStream *)sender;

// 在接收了IQ(消息查詢(xún)后)會(huì)回調(diào)此代理方法

- (BOOL)xmppStream:(XMPPStream *)senderdidReceiveIQ:(XMPPIQ *)iq;

// 在接收了消息后會(huì)回調(diào)此代理方法

- (void)xmppStream:(XMPPStream *)senderdidReceiveMessage:(XMPPMessage *)message;

// 在接收了用戶(hù)在線狀態(tài)消息后會(huì)回調(diào)此代理方法

- (void)xmppStream:(XMPPStream *)senderdidReceivePresence:(XMPPPresence *)presence;

// 在接收IQ/messag、presence出錯(cuò)時(shí)翘盖,會(huì)回調(diào)此代理方法

- (void)xmppStream:(XMPPStream *)senderdidReceiveError:(NSXMLElement *)error;

// 將要發(fā)送IQ(消息查詢(xún)時(shí))時(shí)會(huì)回調(diào)此代理方法

- (XMPPIQ *)xmppStream:(XMPPStream *)senderwillSendIQ:(XMPPIQ *)iq;

// 在將要發(fā)送消息時(shí)桂塞,會(huì)回調(diào)此代理方法

- (XMPPMessage *)xmppStream:(XMPPStream *)senderwillSendMessage:(XMPPMessage *)message;

// 在將要發(fā)送用戶(hù)在線狀態(tài)信息時(shí),會(huì)回調(diào)此方法

- (XMPPPresence *)xmppStream:(XMPPStream *)senderwillSendPresence:(XMPPPresence *)presence;

// 在發(fā)送IQ(消息查詢(xún))成功后會(huì)回調(diào)此代理方法

- (void)xmppStream:(XMPPStream *)senderdidSendIQ:(XMPPIQ *)iq;

// 在發(fā)送消息成功后馍驯,會(huì)回調(diào)此代理方法

- (void)xmppStream:(XMPPStream *)senderdidSendMessage:(XMPPMessage *)message;

// 在發(fā)送用戶(hù)在線狀態(tài)信息成功后阁危,會(huì)回調(diào)此方法

- (void)xmppStream:(XMPPStream *)senderdidSendPresence:(XMPPPresence *)presence;

// 在發(fā)送IQ(消息查詢(xún))失敗后會(huì)回調(diào)此代理方法

- (void)xmppStream:(XMPPStream *)senderdidFailToSendIQ:(XMPPIQ *)iqerror:(NSError *)error;

// 在發(fā)送消息失敗后玛痊,會(huì)回調(diào)此代理方法

- (void)xmppStream:(XMPPStream *)senderdidFailToSendMessage:(XMPPMessage *)messageerror:(NSError *)error;

// 在發(fā)送用戶(hù)在線狀態(tài)失敗信息后,會(huì)回調(diào)此方法

- (void)xmppStream:(XMPPStream *)senderdidFailToSendPresence:(XMPPPresence *)presenceerror:(NSError *)error;

// 當(dāng)修改了JID信息時(shí)狂打,會(huì)回調(diào)此代理方法

- (void)xmppStreamDidChangeMyJID:(XMPPStream *)xmppStream;

// 當(dāng)Stream被告知與服務(wù)器斷開(kāi)連接時(shí)會(huì)回調(diào)此代理方法

- (void)xmppStreamWasToldToDisconnect:(XMPPStream *)sender;

// 當(dāng)發(fā)送了節(jié)點(diǎn)時(shí)擂煞,會(huì)回調(diào)此代理方法

- (void)xmppStreamDidSendClosingStreamStanza:(XMPPStream *)sender;

// 連接超時(shí)時(shí)會(huì)回調(diào)此代理方法

- (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender;

// 當(dāng)與服務(wù)器斷開(kāi)連接后,會(huì)回調(diào)此代理方法

- (void)xmppStreamDidDisconnect:(XMPPStream *)senderwithError:(NSError *)error;

// p2p類(lèi)型相關(guān)的

- (void)xmppStream:(XMPPStream *)senderdidReceiveP2PFeatures:(NSXMLElement *)streamFeatures;

- (void)xmppStream:(XMPPStream *)senderwillSendP2PFeatures:(NSXMLElement *)streamFeatures;

- (void)xmppStream:(XMPPStream *)senderdidRegisterModule:(id)module;

- (void)xmppStream:(XMPPStream *)senderwillUnregisterModule:(id)module;

// 當(dāng)發(fā)送非XMPP元素節(jié)點(diǎn)時(shí)菱父,會(huì)回調(diào)此代理方法颈娜。也就是說(shuō),如果發(fā)送的element不是

// , 或者 浙宜,那么就會(huì)回調(diào)此代理方法

- (void)xmppStream:(XMPPStream *)senderdidSendCustomElement:(NSXMLElement *)element;

// 當(dāng)接收到非XMPP元素節(jié)點(diǎn)時(shí)官辽,會(huì)回調(diào)此代理方法。也就是說(shuō)粟瞬,如果接收的element不是

// , 或者 同仆,那么就會(huì)回調(diào)此代理方法

- (void)xmppStream:(XMPPStream *)senderdidReceiveCustomElement:(NSXMLElement *)element;

到此,也就理解了XMPPStream五五六六了吧H蛊贰K着!

XMPPIQ

消息查詢(xún)(IQ)就是通過(guò)此類(lèi)來(lái)處理的了市怎。XMPP給我們提供了IQ方便創(chuàng)建的類(lèi)岁忘,用于快速生成XML數(shù)據(jù)。若頭文件聲明如下:

@interfaceXMPPIQ: XMPPElement

// 生成iq

+ (XMPPIQ *)iq;

+ (XMPPIQ *)iqWithType:(NSString *)type;

+ (XMPPIQ *)iqWithType:(NSString *)typeto:(XMPPJID *)jid;

+ (XMPPIQ *)iqWithType:(NSString *)typeto:(XMPPJID *)jidelementID:(NSString *)eid;

+ (XMPPIQ *)iqWithType:(NSString *)typeto:(XMPPJID *)jidelementID:(NSString *)eidchild:(NSXMLElement *)childElement;

+ (XMPPIQ *)iqWithType:(NSString *)typeelementID:(NSString *)eid;

+ (XMPPIQ *)iqWithType:(NSString *)typeelementID:(NSString *)eidchild:(NSXMLElement *)childElement;

+ (XMPPIQ *)iqWithType:(NSString *)typechild:(NSXMLElement *)childElement;

- (id)init;

- (id)initWithType:(NSString *)type;

- (id)initWithType:(NSString *)typeto:(XMPPJID *)jid;

- (id)initWithType:(NSString *)typeto:(XMPPJID *)jidelementID:(NSString *)eid;

- (id)initWithType:(NSString *)typeto:(XMPPJID *)jidelementID:(NSString *)eidchild:(NSXMLElement *)childElement;

- (id)initWithType:(NSString *)typeelementID:(NSString *)eid;

- (id)initWithType:(NSString *)typeelementID:(NSString *)eidchild:(NSXMLElement *)childElement;

- (id)initWithType:(NSString *)typechild:(NSXMLElement *)childElement;

// IQ類(lèi)型区匠,看下面的說(shuō)明

- (NSString *)type;

// 判斷type類(lèi)型

- (BOOL)isGetIQ;

- (BOOL)isSetIQ;

- (BOOL)isResultIQ;

- (BOOL)isErrorIQ;

// 當(dāng)type為get或者set時(shí)干像,這個(gè)API是很有用的,用于指定是否要求有響應(yīng)

- (BOOL)requiresResponse;

- (NSXMLElement *)childElement;

- (NSXMLElement *)childErrorElement;

@end

IQ是一種請(qǐng)求/響應(yīng)機(jī)制驰弄,從一個(gè)實(shí)體從發(fā)送請(qǐng)求麻汰,另外一個(gè)實(shí)體接受請(qǐng)求并進(jìn)行響應(yīng)。例如戚篙,client在stream的上下文中插入一個(gè)元素五鲫,向Server請(qǐng)求得到自己的好友列表,Server返回一個(gè)岔擂,里面是請(qǐng)求的結(jié)果位喂。

有以下類(lèi)別(可選設(shè)置如:get):

get :獲取當(dāng)前域值。類(lèi)似于http get方法乱灵。

set :設(shè)置或替換get查詢(xún)的值忆某。類(lèi)似于http put方法。

result :說(shuō)明成功的響應(yīng)了先前的查詢(xún)阔蛉。類(lèi)似于http狀態(tài)碼200。

error: 查詢(xún)和響應(yīng)中出現(xiàn)的錯(cuò)誤癞埠。

下面是一個(gè)IQ例子:

<iqfrom="huangyibiao@welcome.com/ios"? ? ? id="xxxxxxx"? ? to="biaoge@welcome.com/ios"? ? ? type="get">?

XMPPPresence

這個(gè)類(lèi)代表節(jié)點(diǎn)状原,我們通過(guò)此類(lèi)提供的方法來(lái)生成XML數(shù)據(jù)聋呢。它代表用戶(hù)在線狀態(tài),它的頭文件內(nèi)容很少的:

@interfaceXMPPPresence: XMPPElement

// Converts an NSXMLElement to an XMPPPresence element in place (no memory allocations or copying)

+ (XMPPPresence *)presenceFromElement:(NSXMLElement *)element;

+ (XMPPPresence *)presence;

+ (XMPPPresence *)presenceWithType:(NSString *)type;

// type:用戶(hù)在線狀態(tài)颠区,看下面的講解

// to:接收方的JID

+ (XMPPPresence *)presenceWithType:(NSString *)typeto:(XMPPJID *)to;

- (id)init;

- (id)initWithType:(NSString *)type;

// type:用戶(hù)在線狀態(tài)削锰,看下面的講解

// to:接收方的JID

- (id)initWithType:(NSString *)typeto:(XMPPJID *)to;

- (NSString *)type;

- (NSString *)show;

- (NSString *)status;

- (int)priority;

- (int)intShow;

- (BOOL)isErrorPresence;

@end

presence用來(lái)表明用戶(hù)的狀態(tài),如:online毕莱、away器贩、dnd(請(qǐng)勿打擾)等。當(dāng)改變自己的狀態(tài)時(shí)朋截,就會(huì)在stream的上下文中插入一個(gè)Presence元素蛹稍,來(lái)表明自身的狀態(tài)。要想接受presence消息部服,必須經(jīng)過(guò)一個(gè)叫做presence subscription的授權(quán)過(guò)程唆姐。

有以下類(lèi)別(可選設(shè)置如:subscribe):

subscribe:訂閱其他用戶(hù)的狀態(tài)

probe:請(qǐng)求獲取其他用戶(hù)的狀態(tài)

unavailable:不可用,離線(offline)狀態(tài)

節(jié)點(diǎn)有以下類(lèi)別廓八,如dnd:

chat:聊天中

away:暫時(shí)離開(kāi)

xa:eXtend Away奉芦,長(zhǎng)時(shí)間離開(kāi)

dnd:勿打擾

節(jié)點(diǎn)

這個(gè)節(jié)點(diǎn)表示狀態(tài)信息,內(nèi)容比較自由剧蹂,幾乎可以是所有類(lèi)型的內(nèi)容声功。常用來(lái)表示用戶(hù)當(dāng)前心情,活動(dòng)宠叼,聽(tīng)的歌曲先巴,看的視頻,所在的聊天室车吹,訪問(wèn)的網(wǎng)頁(yè)筹裕,玩的游戲等等。

節(jié)點(diǎn)

范圍-128~127窄驹。高優(yōu)先級(jí)的resource能接受發(fā)送到bare JID的消息朝卒,低優(yōu)先級(jí)的resource不能。優(yōu)先級(jí)為負(fù)數(shù)的resource不能收到發(fā)送到bare JID的消息乐埠。

發(fā)送一個(gè)用戶(hù)在線狀態(tài)的例子:

? dnd? 瀏覽器搜索:標(biāo)哥的技術(shù)博客抗斤,或者直接訪問(wèn)www.henishuo.com

XMPPMessage

XMPPMessage是XMPP框架給我們提供的,方便用于生成XML消息的數(shù)據(jù)丈咐,其頭文件如下:

@interfaceXMPPMessage: XMPPElement

+ (XMPPMessage *)messageFromElement:(NSXMLElement *)element;

+ (XMPPMessage *)message;

+ (XMPPMessage *)messageWithType:(NSString *)type;

+ (XMPPMessage *)messageWithType:(NSString *)typeto:(XMPPJID *)to;

+ (XMPPMessage *)messageWithType:(NSString *)typeto:(XMPPJID *)jidelementID:(NSString *)eid;

+ (XMPPMessage *)messageWithType:(NSString *)typeto:(XMPPJID *)jidelementID:(NSString *)eidchild:(NSXMLElement *)childElement;

+ (XMPPMessage *)messageWithType:(NSString *)typeelementID:(NSString *)eid;

+ (XMPPMessage *)messageWithType:(NSString *)typeelementID:(NSString *)eidchild:(NSXMLElement *)childElement;

+ (XMPPMessage *)messageWithType:(NSString *)typechild:(NSXMLElement *)childElement;

- (id)init;

- (id)initWithType:(NSString *)type;

- (id)initWithType:(NSString *)typeto:(XMPPJID *)to;

- (id)initWithType:(NSString *)typeto:(XMPPJID *)jidelementID:(NSString *)eid;

- (id)initWithType:(NSString *)typeto:(XMPPJID *)jidelementID:(NSString *)eidchild:(NSXMLElement *)childElement;

- (id)initWithType:(NSString *)typeelementID:(NSString *)eid;

- (id)initWithType:(NSString *)typeelementID:(NSString *)eidchild:(NSXMLElement *)childElement;

- (id)initWithType:(NSString *)typechild:(NSXMLElement *)childElement;

- (NSString *)type;

- (NSString *)subject;

- (NSString *)body;

- (NSString *)bodyForLanguage:(NSString *)language;

- (NSString *)thread;

- (void)addSubject:(NSString *)subject;

- (void)addBody:(NSString *)body;

- (void)addBody:(NSString *)bodywithLanguage:(NSString *)language;

- (void)addThread:(NSString *)thread;

- (BOOL)isChatMessage;

- (BOOL)isChatMessageWithBody;

- (BOOL)isErrorMessage;

- (BOOL)isMessageWithBody;

- (NSError *)errorMessage;

@end

message是一種基本推送消息方法瑞眼,它不要求響應(yīng)。主要用于IM棵逊、groupChat伤疙、alert和notification之類(lèi)的應(yīng)用中。

有以下類(lèi)別(可選設(shè)置如: chat):

normal:類(lèi)似于email,主要特點(diǎn)是不要求響應(yīng)徒像;

chat:類(lèi)似于qq里的好友即時(shí)聊天黍特,主要特點(diǎn)是實(shí)時(shí)通訊;

groupchat:類(lèi)似于聊天室里的群聊锯蛀;

headline:用于發(fā)送alert和notification灭衷;

error:如果發(fā)送message出錯(cuò),發(fā)現(xiàn)錯(cuò)誤的實(shí)體會(huì)用這個(gè)類(lèi)別來(lái)通知發(fā)送者出錯(cuò)了旁涤;

節(jié)點(diǎn)

所要發(fā)送的內(nèi)容就放在body節(jié)點(diǎn)下

消息節(jié)點(diǎn)的例子:

<messageto="lily@jabber.org/contact" type="chat">? ? 您好翔曲?您的博客名是叫標(biāo)哥的技術(shù)博客嗎?地址是http://www.henishuo.com嗎劈愚?

最后

本篇文章就到此為止吧瞳遍,講了那么多,再講下去可能連筆者都暈了~好好只收吧造虎!如果文章中有錯(cuò)誤的地方傅蹂,請(qǐng)大家在評(píng)論中提出或者直接在QQ上聯(lián)系筆者!謝謝~

期待下一篇吧~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末算凿,一起剝皮案震驚了整個(gè)濱河市份蝴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌氓轰,老刑警劉巖惶洲,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件累澡,死亡現(xiàn)場(chǎng)離奇詭異该默,居然都是意外死亡绊诲,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)靴庆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)时捌,“玉大人,你說(shuō)我怎么就攤上這事炉抒∩萏郑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵焰薄,是天一觀的道長(zhǎng)拿诸。 經(jīng)常有香客問(wèn)我,道長(zhǎng)塞茅,這世上最難降的妖魔是什么亩码? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮野瘦,結(jié)果婚禮上描沟,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好啊掏,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布蠢络。 她就那樣靜靜地躺著,像睡著了一般迟蜜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上啡省,一...
    開(kāi)封第一講書(shū)人閱讀 49,842評(píng)論 1 290
  • 那天娜睛,我揣著相機(jī)與錄音,去河邊找鬼卦睹。 笑死畦戒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的结序。 我是一名探鬼主播障斋,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼徐鹤!你這毒婦竟也來(lái)了垃环?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤返敬,失蹤者是張志新(化名)和其女友劉穎遂庄,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體劲赠,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涛目,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凛澎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霹肝。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖塑煎,靈堂內(nèi)的尸體忽然破棺而出沫换,到底是詐尸還是另有隱情,我是刑警寧澤轧叽,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布苗沧,位于F島的核電站,受9級(jí)特大地震影響炭晒,放射性物質(zhì)發(fā)生泄漏待逞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一网严、第九天 我趴在偏房一處隱蔽的房頂上張望识樱。 院中可真熱鬧,春花似錦、人聲如沸怜庸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)割疾。三九已至嚎卫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宏榕,已是汗流浹背拓诸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留麻昼,地道東北人奠支。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像抚芦,于是被迫代替她去往敵國(guó)和親倍谜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • XMPPFramework結(jié)構(gòu) 在進(jìn)入下一步之前叉抡,先給大家講講XMPPFramework的目錄結(jié)構(gòu)尔崔,以便新手們更容...
    啓蘊(yùn)閱讀 580評(píng)論 0 0
  • XMPP簡(jiǎn)介 原理 概述XMPP(可擴(kuò)展消息處理現(xiàn)場(chǎng)協(xié)議)是基于可擴(kuò)展標(biāo)記語(yǔ)言(XML)的協(xié)議,它用于即時(shí)消息(I...
    樂(lè)小文閱讀 6,189評(píng)論 1 9
  • 時(shí)間過(guò)得很快,我的第一份iOS工作做的就是IM應(yīng)用(選用的是XMPP),如今也忘得差不多了.利用空閑時(shí)間來(lái)重寫(xiě)一遍...
    飄金閱讀 2,955評(píng)論 2 2
  • 注冊(cè)卜壕,獲取好友列表您旁,聊天 我們的注冊(cè)功能實(shí)現(xiàn)上跟登錄功能的步驟大致相當(dāng) 首先需要在我們的XMPPManager類(lèi)中...
    Axela閱讀 592評(píng)論 1 0
  • 我?guī)煾高€說(shuō):有智慧,就知道在什么場(chǎng)合轴捎,面對(duì)什么人鹤盒,該說(shuō)什么話(huà),在不同環(huán)境下找到自己的位置侦副。眾生受苦侦锯,是因?yàn)樵爝^(guò)惡業(yè)...
    啟蒙班煒興媽媽黃玉茹閱讀 246評(píng)論 0 0