XMPP系列(二)----用户注册和用户登录功能
1.创建一个新工程
2.导入XMPP框架
最新的XMPP框架下载地址:https://github.com/robbiehanson/XMPPFramework
将XMPP的几个文件夹拖进工程中,需要的文件如下:
然后把Sample_XMPPFramework.h改名为XMPPFramework.h
接下来导入两个依赖库:libresolv.dylib和libxml2.dylib,然后添加header search:
再添加一个pch文件
在pch文件中添加如下代码:
#ifdef __OBJC__
#import <UIKit/UIKit.h> #import "XMPPFramework.h"
#endif
再然后设置工程的pch文件
$SRCROOT后面是项目名/pch文件名。
做完以上步骤,项目就可以编译成功啦!
现在开始搭建项目的登录界面:
首先封装一个XMPP工具类:JKXMPPTool
.h文件
#import <Foundation/Foundation.h> @interface JKXMPPTool : NSObject<XMPPStreamDelegate> @property (nonatomic, strong) XMPPStream *xmppStream;
// 模块
@property (nonatomic, strong) XMPPAutoPing *xmppAutoPing;
@property (nonatomic, strong) XMPPReconnect *xmppReconnect; @property (nonatomic, assign) BOOL xmppNeedRegister;
@property (nonatomic, copy) NSString *myPassword; + (instancetype)sharedInstance;
- (void)loginWithJID:(XMPPJID *)JID andPassword:(NSString *)password;
- (void)registerWithJID:(XMPPJID *)JID andPassword:(NSString *)password; @end
.m文件
#import "JKXMPPTool.h" @implementation JKXMPPTool static JKXMPPTool *_instance;
+ (instancetype)sharedInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [JKXMPPTool new];
}); return _instance;
} - (XMPPStream *)xmppStream
{
if (!_xmppStream) {
_xmppStream = [[XMPPStream alloc] init]; //socket 连接的时候 要知道host port 然后connect
[self.xmppStream setHostName:kXMPP_HOST];
[self.xmppStream setHostPort:kXMPP_PORT];
//为什么是addDelegate? 因为xmppFramework 大量使用了多播代理multicast-delegate ,代理一般是1对1的,但是这个多播代理是一对多得,而且可以在任意时候添加或者删除
[self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()]; }
return _xmppStream;
} - (void)loginWithJID:(XMPPJID *)JID andPassword:(NSString *)password
{
// 1.建立TCP连接
// 2.把我自己的jid与这个TCP连接绑定起来(即使匿名登录,依然得设置JID,只是我们可以设置一个任意的JID,例如<span style="font-family: Arial, Helvetica, sans-serif;">anonymous@<domain></span>)
// 3.认证(登录:验证jid与密码是否正确,加密方式 不可能以明文发送)--(出席:怎样告诉服务器我上线,以及我得上线状态
//这句话会在xmppStream以后发送XML的时候加上 <message from="JID">
[self.xmppStream setMyJID:JID];
self.myPassword = password;
self.xmppNeedRegister = NO;
[self.xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:nil];
} //注册方法里没有调用auth方法
- (void)registerWithJID:(XMPPJID *)JID andPassword:(NSString *)password
{
[self.xmppStream setMyJID:JID];
self.myPassword = password;
self.xmppNeedRegister = YES;
[self.xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:nil];
} - (void)goOnline
{
// 发送一个<presence/> 默认值avaliable 在线 是指服务器收到空的presence 会认为是这个
XMPPPresence *presence = [XMPPPresence presence]; //发送复杂一点的出席状态
//<presence type="avaliable">
// <status>我很忙</status>
// <show>xa</show>
// </presence>
[presence addChild:[DDXMLNode elementWithName:@"status" stringValue:@"我现在很忙"]];
[presence addChild:[DDXMLNode elementWithName:@"show" stringValue:@"xa"]]; [self.xmppStream sendElement:presence];
} #pragma mark ===== XMPPStream delegate =======
//socket 连接建立成功
- (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket
{
NSLog(@"%s",__func__);
} //这个是xml流初始化成功
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
NSLog(@"%s",__func__);
//匿名登录 会随机生成一个username和JID,这个是在服务器的内存中随机生成,不会写入服务器的数据表,例如生成的jid为<p class="p1"><span class="s1">1nv8l4khxg@im.joker.cn/1nv8l4khxg</span></p>
//为了防止客户端匿名登录,服务器有策略关闭匿名
// [self.xmppStream authenticateAnonymously:nil];
if (self.xmppNeedRegister) {
[self.xmppStream registerWithPassword:self.myPassword error:nil];
} else {
[self.xmppStream authenticateWithPassword:self.myPassword error:nil];
}
} - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{
NSLog(@"%s",__func__);
} //登录失败
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error
{
NSLog(@"%s",__func__);
} //登录成功
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
NSLog(@"%s",__func__); [self goOnline]; [[NSNotificationCenter defaultCenter] postNotificationName:kLOGIN_SUCCESS object:nil];
} @end
然后是登录功能:
登录按钮的action如下:
#pragma mark - click event
/** 登录事件 */
- (IBAction)loginClick:(id)sender {
NSString *username = _usernameField.text;
NSString *password = _passwordField.text; NSString *message = nil;
if (username.length <= 0) {
message = @"用户名未填写";
} else if (password.length <= 0) {
message = @"密码未填写";
} if (message.length > 0) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:@"我知道了" otherButtonTitles:nil];
[alertView show];
} else {
[[JKXMPPTool sharedInstance] loginWithJID:[XMPPJID jidWithUser:username domain:@"im.joker.cn" resource:@"iOS"] andPassword:password];
}
}
用通知返回登录成功的消息
- (void)loginSuccess
{
NSLog(@"loginSuccess"); [self performSegueWithIdentifier:@"loginSegue" sender:self];
}
再然后实现注册的功能:
- (IBAction)registAction:(id)sender {
NSString *username = _usernameField.text;
NSString *password = _passwordField.text;
NSString *confirm = _confirmField.text;
NSString *message = nil;
if (username.length <= 0) {
message = @"用户名未填写";
} else if (password.length <= 0) {
message = @"密码未填写";
} else if (confirm.length <= 0) {
message = @"确认密码未填写";
}
if (message.length > 0) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:@"我知道了" otherButtonTitles:nil];
[alertView show];
} else if (![password isEqualToString:confirm]) {
message = @"密码与确认密码不一致";
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:@"我知道了" otherButtonTitles:nil];
[alertView show];
} else {
[[JKXMPPTool sharedInstance] registerWithJID:[XMPPJID jidWithUser:username domain:@"im.joker.cn" resource:@"iOS"] andPassword:password];
}
}
因为注册时,不需要进行认证,注册会直接返回BOOL结果,所以改进连接代理方法:
//这个是xml流初始化成功
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
NSLog(@"%s",__func__);
if (self.xmppNeedRegister) {
BOOL result = [self.xmppStream registerWithPassword:self.myPassword error:nil];
NSNumber *number = [NSNumber numberWithBool:result]; [[NSNotificationCenter defaultCenter] postNotificationName:kREGIST_RESULT object:number]; } else {
[self.xmppStream authenticateWithPassword:self.myPassword error:nil];
}
}
下载地址:点击下载
github地址:https://github.com/Joker-King/ChatDemo
XMPP系列(二)----用户注册和用户登录功能的更多相关文章
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- Struts2整合Hibernate3实现用户登录功能
所用技术:struts2 ,hibernate,jsp,mysql 本DEMO仅仅实现用户登录功能,采用MVC思想,自己也觉得相对是比较简单,比较容易理解数据流向的一个例子,通过整合这个过程,能够清晰 ...
- JavaWeb学习记录(六)——用户登录功能
使用JDBC.spring框架.servlet实现一个简单的用户登录功能. 一.mySql数据库 SET FOREIGN_KEY_CHECKS=0; -- ---------------------- ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(五)——实现注册功能
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(四)——对 run.py 的调整
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(三)——使用Flask-Login库实现登录功能
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- .net reactor 学习系列(二)---.net reactor界面各功能说明
原文:.net reactor 学习系列(二)---.net reactor界面各功能说明 安装了.net reactor之后,可以在安装目录下找到帮助文档REACTOR_HELP.c ...
- 实现Web上的用户登录功能
关于如何实现web上的自动登录功能 文章来源http://coolshell.cn/articles/5353.html Web上的用户登录功能应该是最基本的功能了,可是在我看过一些站点的用户登录功能 ...
随机推荐
- FFmpeg的HEVC解码器源代码简单分析:环路滤波(Loop Filter)
===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...
- Storm 0.9安装指南
Storm 0.9.2安装指南 0 Storm0.9的亮点 引用网上的描述: "Storm 0.9.0.1版本的第一亮点是引入了netty transport.Storm网络传输机制实现可插 ...
- UNIX环境高级编程——初始化一个守护进程
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h&g ...
- Cocos2D实现RPG游戏人物地图行走的跟随效果
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在一些RPG游戏中,人物队列在地图中行走的时候有时需要实现一个 ...
- UNIX网络编程——套接字选项(setsockopt)
setsockopt的一些用法: close socket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket: BOOL bReuseaddr=TRUE; setsockop ...
- Gradle笔记——关于Gradle 1.12
到目前为止,Gradle已经出到2.1版本了,从1.12这个版本开始看,主要是因为我使用Gradle是Android开发所需要.公司里面是采用Android Studio来进行Android项目的开发 ...
- svn 回退/更新/取消至某个版本命令详解
1. 取消Add/Delete 取消文件 svn revert 文件名 取消目录 svn revert --depth=infinity 目录名 2. 回退版本 方法1: 用svn merge 1) ...
- 查看Linux下的文件
到了这个时候了,也大概的知道了寄出的Linux的操作,是时候接触一下如何查看文件了.我们常用的有以下几种方式: 1.cat,使用cat命令可以将文件的内容输出到显示屏上,也可以将两个文件结合一起输出. ...
- (NO.00002)iOS游戏精灵战争雏形(十一)
为了在子弹触碰到目标时做一些事情,我们必须要设置碰撞回调. 首先在MainScene.h的类接口中添加碰撞协议: @interface MainScene : CCNode <CCPhysics ...
- OJ题:字符串最后一个单词的长度
题目描述 计算字符串最后一个单词的长度,单词以空格隔开. 输入描述: 一行字符串,非空,长度小于5000. 输出描述: 整数N,最后一个单词的长度. 输入例子: hello world 输出例子: 5 ...