轉:xmppframework相關學習 【iOS XMPP】使用XMPPFramewok(一):添加XMPPFramework(XCode 4.6.2) 【iOS XMPP】使用XMPPFramewo

【iOS XMPP】使用XMPPFramewok(一):添加XMPPFramework(XCode 4.6.2)

XMPPFrameworkhtml

GitHub: https://github.com/robbiehanson/XMPPFrameworkgit

 

獲取源代碼github

git clone https://github.com/robbiehanson/XMPPFramework.git服務器

checkout XMPPFramework 一個最新的 branch框架

 

添加依賴dom

> 拷貝 <XMPPFramework>/Vendor/CocoaLumberjack 到項目根目錄下,add files...,選擇 CocoaLumberjack 文件夾post

> 一樣的步驟,拷貝 CocoaAsyncSocket 和 KissXML 並添加到項目中ui

CocoaAsyncSocket 依賴 CFNetwork.framework 和 Security.framework,在 TARGETS -> Build Phases -> Link Binary With Libraries 添加this

KissXML 使用了 libxml2 解析 XML,因此url

首先,咱們須要在 TARGETS -> Build Phases -> Link Binary With Libraries 添加 libXML2.dylib

而後,在 TARGETS -> Build Settings -> Other Linker Flags 添加 -lxml2,TARGETS -> Build Settings -> Header Search Paths 添加 /usr/include/libxml2

> 拷貝 <XMPPFramework>/Vendor/libidn 到項目根目錄下,添加靜態庫文件 libidn.a 和頭文件 idn-int.h 和 stringprep.h

 

添加 XMPPFramework

拷貝源碼目錄下的 Authentication Categories Core 和 Utilities 到項目根目錄下並添加到項目中

此外,須要添加動態鏈接庫 libresolv.dylib ,在 TARGETS -> Build Phases -> Link Binary With Libraries 添加

 

添加擴展

你能夠根據本身的須要,添加 <XMPPFramework>/Extensions 的擴展到項目中 

你可能遇到的問題:

> "XMPPFramework.h" file not found

XMPPFramework.h 內容以下,可根據實際使用模塊進行刪改:

複製代碼
#import "XMPP.h"

// List the modules you're using here.

#import "XMPPReconnect.h"

#import "XMPPRoster.h"
#import "XMPPRosterCoreDataStorage.h"

#import "XMPPvCardTempModule.h"
#import "XMPPvCardAvatarModule.h"
#import "XMPPvCardCoreDataStorage.h"

#import "XMPPCapabilities.h"
#import "XMPPCapabilitiesCoreDataStorage.h"

#import "XMPPMUC.h"
#import "XMPPRoomCoreDataStorage.h"
複製代碼

 

還有一些問題,是因爲沒有添加Extension須要的依賴庫所產生的

可在 TARGETS -> Build Phases -> Link Binary With Libraries 添加

CoreData.framework SystemConfiguration.framework CoreLocation.framework

 

ARC 警告

XMPPFramework 使用 ARC,若是你的項目沒有使用 ARC,build 以後你會獲得許許多多的 ARC 警告。

不要忽視這些警告,它會致使你的程序因 memory leak 而崩潰……

Edit -> Refactor -> convert to Objective-C ARC,消滅這些警告!

 

參考: https://github.com/robbiehanson/XMPPFramework/wiki/GettingStarted_iOS

 

【iOS XMPP】使用XMPPFramewok(二):用戶登陸

用戶登陸

 

準備工做

比較知名的開源XMPP服務器:一個是Openfire,一個是ejabberd

Openfire 使用 Java 語言編寫,比較容易上手,地址:http://www.igniterealtime.org/projects/openfire/

ejabberd 使用 Erlang 語言編寫,是一款很是知名的 Erlang 開源項目,地址:http://www.ejabberd.im/

安裝 ejabberd,能夠參考個人博客:【ejabberd】安裝XMPP服務器ejabberd(Ubuntu 12.04)

搭建一個本身的 XMPP 服務器以後,就讓咱們開始吧!

 

鏈接服務器

一、新建一個 XMPPStream 對象,添加委託

添加委託方法 - (void)addDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue

參數 delegateQueue 爲委託回調所使用的 GCD 隊列,dispatch_get_main_queue() 獲取主線程 GCD 隊列

二、設置 JID 和 主機名

JID 通常由三部分構成:用戶名,域名和資源名,例如 test@example.com/Anthony

若是沒有設置主機名,則使用 JID 的域名做爲主機名

端口號是可選的,默認是 5222

三、鏈接

複製代碼
- (void)connect {
    if (self.xmppStream == nil) {
        self.xmppStream = [[XMPPStream alloc] init];
        [self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
    }
    
    if (![self.xmppStream isConnected]) {
        NSString *username = [[NSUserDefaults standardUserDefaults] objectForKey:@"username"];
        XMPPJID *jid = [XMPPJID jidWithUser:username domain:@"lizhen" resource:@"Ework"];
        [self.xmppStream setMyJID:jid];
        [self.xmppStream setHostName:@"10.4.125.113"];
        NSError *error = nil;
        if (![self.xmppStream connect:&error]) {
            NSLog(@"Connect Error: %@", [[error userInfo] description]);
        }
    }
}
複製代碼

 

身份認證

實現 - (void)xmppStreamDidConnect:(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.

身份認證方法 - (BOOL)authenticateWithPassword:(NSString *)inPassword error:(NSError **)errPtr

複製代碼
- (void)xmppStreamDidConnect:(XMPPStream *)sender {
    NSString *password = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
    NSError *error = nil;
    if (![self.xmppStream authenticateWithPassword:password error:&error]) {
        NSLog(@"Authenticate Error: %@", [[error userInfo] description]);
    }
}
複製代碼

 

上線

實現 - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender 委託方法

身份認證成功後,回調該方法

This method is called after authentication has successfully finished. 

If authentication fails for some reason, the xmppStream:didNotAuthenticate: method will be called instead.

新建一個 XMPPPresence 對象,類型爲 available,發送!

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"available"];
    [self.xmppStream sendElement:presence];
}

 

退出並斷開鏈接

新建一個 XMPPPresence 對象,類型爲 unavailable,發送!

斷開鏈接

- (void)disconnect {
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
    [self.xmppStream sendElement:presence];
    
    [self.xmppStream disconnect];
}

 

 

【iOS XMPP】使用XMPPFramewok(三):好友狀態

好友狀態

 

獲取好友狀態,經過實現 

- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence

方法

當接收到 <presence /> 標籤的內容時,XMPPFramework 框架回調該方法

 

一個 <presence /> 標籤的格式通常以下:

<presence from="">

  <show>這裏是顯示的內容<show />

  <status>這裏是顯示的狀態<status />

<presence />

presence 的狀態:

available 上線

away 離開

do not disturb 忙碌

unavailable 下線

 

複製代碼
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence {
    NSString *presenceType = [presence type];
    NSString *presenceFromUser = [[presence from] user];
    if (![presenceFromUser isEqualToString:[[sender myJID] user]]) {
        if ([presenceType isEqualToString:@"available"]) {
            //
        } else if ([presenceType isEqualToString:@"unavailable"]) {
            //
        }
    }
}
複製代碼

 

 

【iOS XMPP】使用XMPPFramewok(四):收發消息

收發消息

 

接收消息

經過實現 

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message;

方法

當接收到 <message /> 標籤的內容時,XMPPFramework 框架回調該方法

根據 XMPP 協議,消息體的內容存儲在標籤 <body /> 內

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message {
    NSString *messageBody = [[message elementForName:@"body"] stringValue];
}

 

發送消息

發送消息,咱們須要根據 XMPP 協議,將數據放到 <message /> 標籤內,例如:

<message type="chat" to="xiaoming@example.com">

  <body>Hello World!<body />

<message />

複製代碼
- (void)sendMessage:(NSString *) message toUser:(NSString *) user {
    NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
    [body setStringValue:message];
    NSXMLElement *message = [NSXMLElement elementWithName:@"message"];
    [message addAttributeWithName:@"type" stringValue:@"chat"];
    NSString *to = [NSString stringWithFormat:@"%@@example.com", user];
    [message addAttributeWithName:@"to" stringValue:to];
    [message addChild:body];
    [self.xmppStream sendElement:message];
}
複製代碼

 

【iOS XMPP】使用XMPPFramewok(五):好友列表

好友列表

 

好友列表,在 XMPP 中被稱爲 roster,花名冊?

獲取 roster 須要客戶端發送 <iq /> 標籤向 XMPP 服務器端查詢

 

一個 IQ 請求:

<iq type="get"

  from="xiaoming@example.com"

  to="example.com"

  id="1234567">

  <query xmlns="jabber:iq:roster"/>

<iq />

type 屬性,說明了該 iq 的類型爲 get,與 HTTP 相似,向服務器端請求信息

from 屬性,消息來源,這裏是你的 JID

to 屬性,消息目標,這裏是服務器域名

id 屬性,標記該請求 ID,當服務器處理完畢請求 get 類型的 iq 後,響應的 result 類型 iq 的 ID 與 請求 iq 的 ID 相同

<query xmlns="jabber:iq:roster"/> 子標籤,說明了客戶端須要查詢 roster

 

複製代碼
- (void)queryRoster {
    NSXMLElement *query = [NSXMLElement elementWithName:@"query" xmlns:@"jabber:iq:roster"];
    NSXMLElement *iq = [NSXMLElement elementWithName:@"iq"];
    XMPPJID *myJID = self.xmppStream.myJID;
    [iq addAttributeWithName:@"from" stringValue:myJID.description];
    [iq addAttributeWithName:@"to" stringValue:myJID.domain];
    [iq addAttributeWithName:@"id" stringValue:[self generateID]];
    [iq addAttributeWithName:@"type" stringValue:@"get"];
    [iq addChild:query];
    [self.xmppStream sendElement:iq];
}
複製代碼

 

一個 IQ 響應:

<iq type="result"

  id="1234567"

  to="xiaoming@example.com">

  <query xmlns="jabber:iq:roster">

    <item jid="xiaoyan@example.com" name="小燕" />

    <item jid="xiaoqiang@example.com" name="小強"/>

  <query />

<iq />

type 屬性,說明了該 iq 的類型爲 result,查詢的結果

<query xmlns="jabber:iq:roster"/> 標籤的子標籤 <item />,爲查詢的子項,即爲 roster

item 標籤的屬性,包含好友的 JID,和其它可選的屬性,例如暱稱等。

 

經過實現

- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq;

方法

當接收到 <iq /> 標籤的內容時,XMPPFramework 框架回調該方法

複製代碼
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq {
    if ([@"result" isEqualToString:iq.type]) {
        NSXMLElement *query = iq.childElement;
        if ([@"query" isEqualToString:query.name]) {
            NSArray *items = [query children];
            for (NSXMLElement *item in items) {
                NSString *jid = [item attributeStringValueForName:@"jid"];
                XMPPJID *xmppJID = [XMPPJID jidWithString:jid];
                [self.roster addObject:xmppJID];
            }
        }
    }
}
複製代碼

 轉自:

知識共享許可協議
本做品採用知識共享署名-非商業性使用 3.0 許可協議進行許可。
轉載請署名李震(博客地址:http://www.cnblogs.com/dyingbleed/),且不得用於商業目的。

相關文章
相關標籤/搜索