我们需要与服务器连接,可以创建一个XMPP的管理类,负责处理客户端与服务器端的交互
我们来创建一个XMPPManager类,继承NSObject
因为XMPPManager这个类他是负责整个客户端与服务器端的即时通讯,所以他只需要一个实例就可以了,我们来创建一个单例。
XMPP框架里有个类,叫做XMPPStream,通信管道,他是负责客户端和服务端的数据传输
就好比你拿一台座机跟你的朋友打电话一样,这台电话需要一个电话线才可以
首先我们要引入XMPPFrameWork的框架
然后我们来创建一个XMPPStream的对象 ,创建完了以后我们要对他进行一个初始化
创建完这个对象后,我们要给他指定服务器的IP地址,XMPPStream有一个属性
叫做hostName,我们这里定义了一个宏,叫做kHostName,我们可以点进去看一下
除了服务器地址外呢,我们还需要给XMPPStream设置一个端口号
什么是端口号呢?
我们的服务器内储存的都是服务,可能有sqlite服务,email服务,或者我们的XMPP服务
每一个服务都有对应的一个端口号,就好比你出去面试一样,一家公司告诉你,我们公司在望京SOHO大楼里,几楼,几号,这个望京SOHO就相当于是一个服务器,里面存储着的各家公司就好比是服务,而每家公司都肯定会有一个自己的门牌号,要没有这些的话,公司邀请你面试,告诉你我们在望京SOHO,你来吧,门牌号没有,自己找,你肯定会想,逗我玩呢?
所以我们的服务是必须要有端口号的,这样才可以让我们准确地找到我们的服务,来进行实现我们要得功能
我们的XMPPStream有一个属性,叫做hostPort,我们这里也定义了一个宏
XMPP使用的openfire他有一个默认的端口是5222,我们把5222设定为了一个宏
有了这两个之后他就明白你要连接到服务器的哪个服务了
最后我们要当前的这个对象成为XMPPStream的代理对象,因为你要向服务器发送连接请求
那么你可能连接成功也可能连接失败,和我们的HTTP请求一样
那么这个连接成功与失败需要我们的一个协议方法来告知我们结果
所以我们要当前对象成为XMPPStream代理对象
首先我们要遵循XMPPStream的一个协议
然后我们添加一个代理方法
[self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
通常我们使用代理的时候都是setDelegate 那么一个对象只能设置一个代理对象
这里比较特殊,待会我们就可以看到这里使用添加代理对象有什么样的好处
然后我们就可以向服务器发送连接请求
我们写一个方法,专门为服务器发送连接请求
//连接请求
(void)connectToServer
我们有了连接,当然也不能少了断开方法
//断开连接
(void)disconnectWithServer
连接的时候我们要进行一个判断,判断当前是否正在链接
[self.xmppStream isConnected];
如果正在连接,我们断开连接
[self disconnectWithServer];
为什么要这么做呢?
就比如你现在和你得A朋友正在打电话,但是你又想给C朋友打电话,那你不得把这边挂了才能给那边打过去吗?
那么断开之后,就可以向服务器发送链接,在向服务器发送链接之前呢
你需要告诉服务器,你是谁
在XMPP框架中呢,有一个XMPPJID类,JID呢,是Jabber ID的缩写,因为我们的XMPP其实就是基J于Jabber协议的基础开发的,JID就是XMPP中得唯一标示
我们可以创建一个XMPPJID,我们来看一下他的初始化方法
XMPPJID *jid = [XMPPJID jidWithUser:(NSString *)domain:(NSString *) resource:(NSString *)];
user就是你得用户名domain是域名,配置openfire给他的域名 resource客户端的来源,比如你得QQ,比如iPhone或者window或者是Android
我们这里定义的有宏,domain这里的openfire给的域名一致就可以了。
那我们这里的user给什么呢?我们这个用户名可以使用一个接口就行了。
XMPPManager里面有一个方法
- (void)loginWithUser:(NSString *)user password:(NSString *)password
我们把XMPPJID *jid = [XMPPJID jidWithUser:(NSString *)domain:kDomain resource:kResource];写入里面
这个时候我们可以把第一个参数写为user
我们这个xmppStream里有个参数为myJID 把他等于jid;
然后就可以进行连接
NSError *error = nil;
[self.xmppStream connectWithTimeout:30.0f error:&error];
判断一下我们的错误信息
if (nil != error )
{
NSLog(@“%s__%d__|链接出错:%@”,__FUNCTION__,__LINE__,error);
}
进行链接的时候会有两种结果,一种是成功,一种失败
那我们需要通过XMPP的协议去实现这两种方法
第一个是成功的
//与服务器链接成功
(void)xmppStreamDidConnect:(XMPPStream *)sender
//与服务器链接失败
(void)xmppStreamConnectDidTimeout:(XMPPStream *)sender
在两个方法内分别打印一下
NSLog(@“%s__%d__|”,__FUNCTION__,__LINE__);
我们回到我们的登录页面
在登录按钮的方法内写入我们的登录方法
[[XMPPManager defaultManager] loginWithUser:userName password:password];
我们来验证一下,运行以后点击登录,打印的是[XMPPManager xmppStreamDidConnect];
我们看这里是xmppStreamDidConnect
我们点进xmppStream代理方法里看一看这个方法
注释内容为This method is called after registration of a new user has successfully finished
翻译一下为:调用此方法后注册一个新用户已经成功完成
这里我们的登录方法内还有一个password没有使用,我们现在只是向服务器发送了链接请求
而没有去验证自己的身份,这个时候就要使用password来验证
我们在链接服务器成功地方法内写一下
[self.xmppStream authenticateWithPassword:(NSString *) error:(NSError *_autoreleasing *)];
这里的password是在
- (void)loginWithUser:(NSString *)user password:(NSString *)password
方法里地,所以我们需要调用一下这个方法给传过来,我们要保存一下
声明一个变量
这里这个验证也是向服务器发送验证
自然也有验证结果,一个成功一个失败
这个结果我们还是要传回登录界面,倒不如我们在登录界面直接获取
怎么获取呢?
我们之前有提到过
xmppStream是可以添加多个对象的,既然我们这个XMPPManager可以成为他的代理对象
那我们的登录界面自然也可以成为他的代理对象,我们在登录界面添加一下这个代理对象
我们来实现以下他的协议方法。
//验证成功
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
NSLog(@"%s__%d__|",__FUNCTION__,__LINE__);
}
//验证失败
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error
{
NSLog(@"%s__%d__|验证失败:%@",__FUNCTION__,__LINE__,error);
}
运行以下,可以看到走的方法是xmppStreamDidAuthenticate,
证明我们验证成功了。
那我们登录成功地话,是不是应该把这个登录界面dimiss呢?
在验证成功地方法内添加一下dismiss的方法
我们如何实现登录过以后,下次不再出现登录界面呢?这个时候就需要用到我们数据持久化的方法
对用户名和密码进行存储
我们依然在验证成功地方法内使用
[[NSUserDefaults standardUserDefaults] setObject:self.userName.text forKey:@"userName"];
[[NSUserDefaults standardUserDefaults] setObject:self.passWord.text forKey:@“password"];
先获取我们的用户名和密码
[[NSUserDefaults standardUserDefaults] synchronize];
然后进行保存。(保存到磁盘上)
在下次进入应用的时候应该先判断我们的用户名
首先用一个bool方法来获取一下我们的用户名
然后再进行一个判断,判断我们是否已经登录
代码如下
我们还需要把当前对象添加一个代理,遵循代理方法去进行验证我们的登录是否成功
以上是我们的登录功能。