码迷,mamicode.com
首页 > 其他好文 > 详细

XMPP系列----------用户注册和用户登录功能

时间:2015-07-20 23:28:47      阅读:269      评论:0      收藏:0      [点我收藏+]

标签:xmpp   即时通讯   ios   

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()];
        
        //添加功能模块
        //1.autoPing 发送的时一个stream:ping 对方如果想表示自己是活跃的,应该返回一个pong
        _xmppAutoPing = [[XMPPAutoPing alloc] init];
        //所有的Module模块,都要激活active
        [_xmppAutoPing activate:self.xmppStream];
        
        //autoPing由于它会定时发送ping,要求对方返回pong,因此这个时间我们需要设置
        [_xmppAutoPing setPingInterval:1000];
        //不仅仅是服务器来得响应;如果是普通的用户,一样会响应
        [_xmppAutoPing setRespondsToQueries:YES];
        //这个过程是C---->S  ;观察 S--->C(需要在服务器设置)
        
        //2.autoReconnect 自动重连,当我们被断开了,自动重新连接上去,并且将上一次的信息自动加上去
        _xmppReconnect = [[XMPPReconnect alloc] init];
        [_xmppReconnect activate:self.xmppStream];
        [_xmppReconnect setAutoReconnect:YES];
    }
    return _xmppStream;
}

- (void)loginWithJID:(XMPPJID *)JID andPassword:(NSString *)password
{
    // 1.建立TCP连接
    // 2.把我自己的jid与这个TCP连接绑定起来
    // 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,这个是在服务器的内存中随机生成,不会写入服务器的数据表
    //为了防止客户端匿名登录,服务器有策略关闭匿名
    //    [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系列----------用户注册和用户登录功能

标签:xmpp   即时通讯   ios   

原文地址:http://blog.csdn.net/u011619283/article/details/46958323

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!