搞事前言
在前面一篇博客中說到關(guān)于Openfire的服務(wù)器的搭建,這一篇博客就從登錄注冊開始搞起,其實(shí)發(fā)現(xiàn)很多網(wǎng)上的XMPPFramework的使用博客都是簡單的說一下其中的各種代理方法是干什么用的,各種界面之間的邏輯沒有較為詳細(xì)的講解,所以騷棟準(zhǔn)備從XMPPFramework中各種代理方法的使用情況以及一個簡單的聊天App的邏輯實(shí)現(xiàn),進(jìn)行詳細(xì)的說明講解.恩恩,對于自己寫的示例SDChat也是寫了好幾天了,其中還是存在不少的Bug.我準(zhǔn)備同步更新,一邊改Bug的同時,一邊更新博客.希望大家諒解.
XMPPFramework的工程配置
- XMPPFramework這個我沒有使用cocospod,而是直接手動導(dǎo)入了文件夾.大家可以直接從SDChat中把XMPPFramework的拖到自己的工程中去,也可以從Github上源碼原處下載.
- 我們把XMPPFramework導(dǎo)入工程之后,我們需要手動導(dǎo)入如下的兩個庫.
libxml2.tbd
libresolv.tbd
- 上面的基本就配置完成了,但是我們需要把服務(wù)器文件
XMPPConfig.h
配置完成.我們在工程中需要的配置項(xiàng)目有這么幾個,分別是服務(wù)器的IP地址、服務(wù)器的的端口(默認(rèn)的為5222),openfire的服務(wù)器名稱诬烹、resource(資源,這個可以自行定義).
服務(wù)器名稱我們可以登錄openfire的管理頁面中,進(jìn)行查看和修改.
如果openfire的服務(wù)器是搭建在mac上的話,服務(wù)器的IP地址可以在網(wǎng)絡(luò)偏好設(shè)置中進(jìn)行查看.
配置的過程有兩點(diǎn)是需要注意的,一、如果openfire的服務(wù)器是搭建在mac上的話,服務(wù)器和移動端必須要在同一局域網(wǎng)內(nèi).否則,應(yīng)用是連接不上服務(wù)器的.二,每一次mac的無線網(wǎng)絡(luò)的變動,IP都有可能發(fā)生改變,如果后期連接不上,請注意查看是否是openfire的服務(wù)器的IP發(fā)生了改變.
配置完成的示例如下所示.
#ifndef XMPPSample_XMPPConfig_h
#define XMPPSample_XMPPConfig_h
// openfire服務(wù)器IP地址
#define kHostName @"192.168.3.18"
// openfire服務(wù)器端口 默認(rèn)5222
#define kHostPort 5222
// openfire服務(wù)器名稱
#define kDomin @"127.0.0.1"
// resource(資源)
#define kResource @"ios"
#endif
- 對于info.plist文件其實(shí)也是需要一些相關(guān)的修改的,但是基本上和XMPPFramework沒有太大的關(guān)系,我們會在具體模塊中進(jìn)行說明.
XMPPFramework的登錄功能實(shí)現(xiàn)
由于XMPPFramework的功能比較多,所以我們需要添加一個管理單例SDXmppManager,管理XMPPFramework所有的功能.我們在SDXmppManager.h文件中導(dǎo)入#import "XMPPFramework.h"
.
我們先一瞅SDchat中登錄界面的騷包風(fēng)采.~~~
在XMPPFramework中,登錄注冊功能主要是由XMPPStream這個類來完成的.我們在SDXmppManager單例中創(chuàng)建一個XMPPStream對象屬性用來管理整個應(yīng)用的登錄注冊.
@property(nonatomic,strong)XMPPStream *stream;
然后我們在單例初始化的過程中對XMPPStream對象屬性進(jìn)行初始化,設(shè)置IP地址以及端口號,并且指定代理對象.
self.stream = [[XMPPStream alloc]init];
self.stream.hostName = kHostName;
self.stream.hostPort = kHostPort;
//設(shè)置stream的代理
[self.stream addDelegate:self delegateQueue:dispatch_get_main_queue()];
好了,基本的準(zhǔn)備工作就做完了,接下來.我們先看一下具體登錄流程圖,然后在比對著SDChat中的登錄操作代碼進(jìn)行詳細(xì)的說明.(流程圖尺寸有點(diǎn)大,如果看不清楚,請先下載到本地在查看.)
流程圖中基本所有的代碼操作都是在SDXmppManager這個單例中完成的.登錄首先其實(shí)主要分為兩大步,第一步先連接服務(wù)器,第二步驗(yàn)證密碼.流程圖把兩大部分拆分成好多小的步驟.
我們先看一下如何連接服務(wù)器.如下代碼所示,我們需要判斷是否已經(jīng)連接到服務(wù)器了.如果已經(jīng)連接是需要先斷開連接的,然后使用登錄賬號,服務(wù)器名稱,資源名稱(可省略)配置成基于jabber協(xié)議的由用戶名生成的唯一ID,并配置到stream中去.然后調(diào)用- (BOOL)connectWithTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr
方法連接服務(wù)器.
//與服務(wù)器的建立鏈接
-(void)connectToServerWintUser:(NSString *)name{
if ([self.stream isConnected]) {
[self.stream disconnect];
}
//jid jabberID,是基于jabber協(xié)議的由用戶名生成的唯一ID
self.stream.myJID = [XMPPJID jidWithUser:name domain:kDomin resource:kResource];
NSLog(@"%@",self.stream.myJID);
NSError *error = nil;
//與服務(wù)器建立鏈接.
[self.stream connectWithTimeout:30.0f error:&error];
if (error != nil) {
NSLog(@"連接失敗!");
}
}
上面如果驗(yàn)證成功之后,就會調(diào)用XMPPStream的-(void)xmppStreamDidConnect:(XMPPStream *)sender
這個代理方法,我們需要在這里面進(jìn)行驗(yàn)證密碼.驗(yàn)證密碼比較簡單只需要調(diào)用[self.stream authenticateWithPassword:self.password error:&error];
這一句代碼即可.具體情況如下.因?yàn)樽院偷卿涱愃?所以兩者需要放在了一起.
//與服務(wù)器建立連接
-(void)xmppStreamDidConnect:(XMPPStream *)sender{
NSError *error = nil;
switch (self.type) {
case DoLgin:
[self.stream authenticateWithPassword:self.password error:&error];
if (error != nil) {
NSLog(@"認(rèn)證過程出錯!");
}
break;
case DoRegiser:
[self.stream registerWithPassword:self.regiserPassword error:&error];
if (error != nil) {
NSLog(@"注冊過程出錯!");
}
break;
}
}
驗(yàn)證完成之后,我們需要進(jìn)行一些界面跳轉(zhuǎn)砌们、用戶登錄狀態(tài)的修改以及保存密碼和JID的操作,這些我是放在SDLoginVC這個控制器進(jìn)行的,SDLoginVC這個控制器是登錄界面的控制器.繼承于SDLaunchViewController
,這是我以前寫的可以做動態(tài)背景的頁面的控制器,感興趣的童鞋可以點(diǎn)擊這里看看.在SDLaunchViewController
這個控制器中是有計(jì)時器的,所以我們在頁面跳轉(zhuǎn)的時候要把計(jì)時器(rollTimer和timer)及時的釋放掉.
//登錄成功!跳轉(zhuǎn)頁面(代理實(shí)現(xiàn))
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
XMPPPresence *presence = [XMPPPresence presenceWithType:@"available"];
[[SDXmppManager defaulManager].stream sendElement:presence];
[SDUser defaulUser].jid =[XMPPJID jidWithUser:self.userName.text domain:kDomin resource:kResource];
[SDUser defaulUser].password = self.passWord.text;
[[SDXmppManager defaulManager].roster fetchRoster];
if (self.timer !=nil) {
[self.timer invalidate];
self.timer = nil;
}
if (self.rollTimer != nil) {
[self.rollTimer invalidate];
self.rollTimer = nil;
}
self.view.window.rootViewController = self.contactNC;
}
登錄成功之后,我們就可以對好友列表信息和個人信息進(jìn)行獲取了.這個會在后面的博客中說到.登錄的基本流程就是這樣了.下面我們看一下注冊功能的實(shí)現(xiàn).
XMPPFramework的注冊功能實(shí)現(xiàn)
SDChat中注冊界面如下所示,其實(shí)用戶名稱并沒有用到,這樣的注冊界面在用戶頭像那部分也是出現(xiàn)了Bug的.下一步著重處理.
注冊的邏輯和登錄的邏輯基本是相同的,也是兩大部分,一部分是連接服務(wù)器,第二部分則是驗(yàn)證注冊密碼.主要代碼跟登錄的基本是一致的,就是驗(yàn)證方法有所不同.沿著密碼的方法改為[self.stream registerWithPassword:self.regiserPassword error:&error];
;
主要用到的注冊成功-(void)xmppStreamDidRegister:(XMPPStream *)sender
或者失敗-(void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error
代理方法具體代碼如下所示.我們在注冊成功的方法中進(jìn)行了頁面的跳轉(zhuǎn),在失敗的方法中進(jìn)行了用戶的提醒.
//當(dāng)注冊成功的時候進(jìn)行調(diào)動
-(void)xmppStreamDidRegister:(XMPPStream *)sender{
UIAlertController *alertView = [UIAlertController alertControllerWithTitle:nil message:@"注冊成功!" preferredStyle:UIAlertControllerStyleAlert];
__weak typeof(self)temp = self;
UIAlertAction *action = [UIAlertAction actionWithTitle:@"返回登錄" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[temp popLoginVC];
}];
[alertView addAction:action];
[self presentViewController:alertView animated:YES completion:nil];
}
//當(dāng)注冊不成功的時候進(jìn)行調(diào)用
-(void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error{
[self showAlertViewWithMessage:@"注冊失敗~,請檢查服務(wù)器"];
}
注冊完成之后,我們還可以進(jìn)行個人名片的設(shè)置等操作.后期將在個人的電子模塊這個部分將會說到.今天就不過多的說明了.
結(jié)束
說到這里基本上XMPPFramework的工程配置以及登錄注冊相關(guān)的知識就說完了,下一篇博客騷棟將對XMPPFramework開發(fā)過程中好友列表的獲取進(jìn)行詳細(xì)的說明.最后把SDChat的傳送門送給大家,大家也可以自己先看一下,如果有任何問題,歡迎聯(lián)系騷棟,謝謝大家了.