即时通讯:第一阶段(登录和注册)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了即时通讯:第一阶段(登录和注册)相关的知识,希望对你有一定的参考价值。

首先是配置XMPP环境,然后建立一个工程,需要建立Core Data的项目,要引入三个框架,如下图,因为用到的XMPPFramework第三方框架中用到了XML解析,所以还要在设置中设置Header Search Paths为/usr/include/libxml2,Other Linker Flags改为-lxml2

技术分享

技术分享

技术分享

XMPPManger.h

 1 #import <Foundation/Foundation.h>
 2 #import "XMPPFramework.h"  // 引入
 3 
 4 @interface XMPPManger : NSObject
 5 
 6 /**
 7  *  声明一个通道的属性
 8  */
 9 @property (nonatomic, strong) XMPPStream *xmppStream;
10 
11 // 创建单例
12 + (instancetype)shareMangaged;
13 
14 // 登录的方法
15 - (void)loginWithUserName:(NSString *)userName password:(NSString *)password;
16 
17 // 注册的方法
18 - (void)registerWithUserName:(NSString *)userName password:(NSString *)password;
19 
20 @end

XMPPManger.m

  1 #import "XMPPManger.h"
  2 
  3 // 列举枚举(登录和注册)
  4 typedef NS_ENUM(NSUInteger, ConnectToServerPurpose) {
  5     ConnectToServerPurposeLogin,
  6     ConnectToServerPurposeRegister,
  7 };
  8 
  9 
 10 @interface XMPPManger () <XMPPStreamDelegate>
 11 
 12 // 登录的属性
 13 @property (nonatomic, strong) NSString *userName;  // 用户名
 14 @property (nonatomic, strong) NSString *password;  // 密码
 15 
 16 // 注册的属性
 17 @property (nonatomic, strong) NSString *registerUserName;  // 用户名
 18 @property (nonatomic, strong) NSString *registerPassword;  // 密码
 19 
 20 // 记录当前是登录还是注册
 21 @property (nonatomic) ConnectToServerPurpose connectToserver;
 22 
 23 @end
 24 
 25 
 26 static XMPPManger *xmpp = nil;
 27 
 28 @implementation XMPPManger
 29 
 30 // 实现创建单例
 31 + (instancetype)shareMangaged {
 32     
 33     static dispatch_once_t onceToken;
 34     dispatch_once(&onceToken, ^{
 35         xmpp = [[XMPPManger alloc] init];
 36     });
 37     return xmpp;
 38 }
 39 
 40 
 41 #pragma mark - 创建通道
 42 - (instancetype)init {
 43     
 44     if (self = [super init]) {
 45         
 46         // 初始化通道对象
 47         self.xmppStream = [[XMPPStream alloc] init];
 48         
 49         // 设置openfire服务器地址
 50         self.xmppStream.hostName = kHostName;
 51         
 52         // 设置服务器端口号
 53         self.xmppStream.hostPort = kHostPort;
 54         
 55         // 添加代理
 56         [self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
 57     }
 58     return self;
 59 }
 60 
 61 
 62 #pragma mark - 登录和注册的方法
 63 // 登录的方法实现
 64 - (void)loginWithUserName:(NSString *)userName password:(NSString *)password {
 65     
 66     self.userName = userName;
 67     self.password = password;
 68     
 69     // 记录登录状态
 70     self.connectToserver = ConnectToServerPurposeLogin;
 71     
 72     // 链接服务器
 73     [self linkServer];
 74 }
 75 
 76 // 注册的方法实现
 77 - (void)registerWithUserName:(NSString *)userName password:(NSString *)password {
 78     
 79     self.registerUserName = userName;
 80     self.registerPassword = password;
 81     
 82     // 记录登录状态
 83     self.connectToserver = ConnectToServerPurposeRegister;
 84     
 85     // 链接服务器
 86     [self linkServer];
 87 }
 88 
 89 
 90 #pragma mark - 链接服务器
 91 - (void)linkServer {
 92     
 93     NSString *string = [[NSString alloc] init];
 94     // 区分具体是登录还是注册
 95     switch (self.connectToserver) {
 96         case ConnectToServerPurposeLogin:
 97             string = [NSString stringWithFormat:@"%@", self.userName];
 98             break;
 99         case ConnectToServerPurposeRegister:
100             string = [NSString stringWithFormat:@"%@", self.registerUserName];
101             break;
102             
103         default:
104             break;
105     }
106     
107     // 要链接服务器,要有用户什么认证
108     // 身份证
109     // 参数1:用户名
110     // 参数2:域名
111     // 参数3:资源
112     XMPPJID *jid = [XMPPJID jidWithUser:string domain:kDomin resource:kResource];
113     
114     // 通过通道进行身份验证
115     self.xmppStream.myJID = jid;
116     
117     
118     // 如果当前聊天工具处于链接状态或者已经链接了,此时,你需要去切断链接,【此逻辑不唯一】
119     if ([self.xmppStream isConnected] || [self.xmppStream isConnecting]) {
120         [self disconnectToServer];
121     }
122     
123     // 链接超时
124     NSError *error = nil;
125     [self.xmppStream connectWithTimeout:5 error:&error];
126     
127     if (error) {
128         NSLog(@"服务器链接超时");
129     }
130 }
131 
132 
133 // 断开链接
134 - (void)disconnectToServer {
135     
136     // 当前用户下线了
137     XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
138     
139     // 告诉通道下线了
140     [self.xmppStream sendElement:presence];
141     
142     // 使通道失去链接
143     [self.xmppStream disconnect];
144 }
145 
146 
147 #pragma mark - XMPPStreamDelegate协议方法
148 #pragma mark - 链接超时
149 - (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender {
150     
151     NSLog(@"链接超时");
152 }
153 
154 
155 #pragma mark - 链接成功
156 - (void)xmppStreamDidConnect:(XMPPStream *)sender {
157     
158     NSLog(@"链接成功");
159     
160         // 区分登录和注册进行密码验证
161     switch (self.connectToserver) {
162         case ConnectToServerPurposeLogin:
163             // 登录密码的验证
164             [self.xmppStream authenticateWithPassword:self.password error:nil];
165             break;
166             
167         case ConnectToServerPurposeRegister:
168             // 注册密码的验证
169             [self.xmppStream registerWithPassword:self.registerPassword error:nil];
170             break;
171         default:
172             break;
173     }
174 }
175 
176 
177 #pragma mark - 断开链接
178 - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error {
179     
180     // 1.自己手动断开
181     
182     // 2.被动断开
183     
184     if (error) {
185         NSLog(@"断开链接,error = %@", error);
186     }
187 }
188 
189 
190 #pragma mark - 认证失败(登录失败)
191 - (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error {
192     
193     NSLog(@"认证失败, error = %@", error);
194 }
195 
196 
197 #pragma mark - 认证成功(登录成功)
198 - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
199     
200     // 上线
201     XMPPPresence *presennce = [XMPPPresence presenceWithType:@"available"];
202     [self.xmppStream sendElement:presennce];
203     
204     NSLog(@"登录成功");
205 }
206 
207 @end

LoginViewcontroller.m(登录)

 1 #import "LoginViewcontroller.h"
 2 #import "XMPPManger.h"
 3 
 4 @interface LoginViewcontroller ()
 5 
 6 @property (weak, nonatomic) IBOutlet UITextField *nameLabel;
 7 @property (weak, nonatomic) IBOutlet UITextField *passwordLabel;
 8 
 9 @end
10 
11 @implementation LoginViewcontroller
12 
13 - (void)viewDidLoad {
14     [super viewDidLoad];
15     // Do any additional setup after loading the view.
16 }
17 
18 
19 // 登录按钮点击事件
20 - (IBAction)loginAction:(UIButton *)sender {
21     
22     [[XMPPManger shareMangaged] loginWithUserName:self.nameLabel.text password:self.passwordLabel.text];
23 }
24 
25 @end

RegisterViewController.m(注册)

因为我们使用的是模态推出,所以我们点击注册按钮的同时需要返回到上一页,因此,注册所用的一些方法我们可以放在此文件中写,都在XMPPManger.m中也可以

 1 #import "RegisterViewController.h"
 2 #import "XMPPManger.h"
 3 
 4 @interface RegisterViewController () <XMPPStreamDelegate>
 5 
 6 @property (weak, nonatomic) IBOutlet UITextField *nameTextField;
 7 @property (weak, nonatomic) IBOutlet UITextField *passwordTextfield;
 8 
 9 @end
10 
11 @implementation RegisterViewController
12 
13 - (void)viewDidLoad {
14     [super viewDidLoad];
15     // Do any additional setup after loading the view.
16     
17     [[XMPPManger shareMangaged].xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
18 }
19 
20 
21 // 注册的方法
22 - (IBAction)registerAction:(UIButton *)sender {
23     
24     [[XMPPManger shareMangaged] registerWithUserName:self.nameTextField.text password:self.passwordTextfield.text];
25 }
26 
27 
28 #pragma mark - XMPPStreamDelegate实现协议方法
29 // 实现协议是为了实现需求:注册成功之后dismiss到登录界面
30 // 注册成功
31 - (void)xmppStreamDidRegister:(XMPPStream *)sender {
32     
33     NSLog(@"注册成功");
34     
35     [self dismissViewControllerAnimated:YES completion:^{
36         
37     }];
38 }
39 
40 
41 // 注册失败
42 - (void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error {
43     
44     NSLog(@"注册失败 = %@", error);
45 }
46 
47 @end

以上是关于即时通讯:第一阶段(登录和注册)的主要内容,如果未能解决你的问题,请参考以下文章

ImFire即时通讯系统构建(需求)

详解企业内部即时通讯工具特点

IM即时通讯软件开发之扫码登录功能

团队作业第一阶段十天冲刺——第十天

浅析im即时通讯开发加白名单

IM即时通讯开发如何设计能支撑百万并发的数据库