XMPP登录注册1
1. 环境准备:openfire + mysql 5.1.6 + Xcode5 + XMPP.Framework (至于环境的配置, 请自己百度, 推荐: http://www.cnblogs.com/xiaodao/archive/2013/04/05/3000554.html)
2. cocoapods
1 platform :ios, '7.0' 2 pod "XMPPFramework", "~>3.6.4"
3.工程: ARC + COREDATA + XIB(Storyboard)
4.直奔重点: XMPP工具单例
1. 首先, 创建一个Infromation.h 文件 用来存放我们需要的一些基本信息,比如host之类的。 然后把这个头文件导入pch文件中 注意我的Domains 后边多一个@
1 #ifndef ADXMPP_BE_Information_h 2 #define ADXMPP_BE_Information_h 3 4 #define SERVER @"127.0.0.1" 5 #define DOMAINS @"@127.0.0.1" 6 7 #endif
2. 创建ADXMPPConn 类、 开始编辑我们的XMPP连接、 登录、 注册核心代码
ADXMPPConn.h
1 //
2 // ADXMPPConn.h
3 // ADXMPP_BE
4 //
5 // Created by Dylan on 14-10-8.
6 // Copyright (c) 2014年 Dylan. All rights reserved.
7 //
8
9 #import <Foundation/Foundation.h>
10 #import <XMPP.h>
11
12 /**
13 用来判断当前用户在进行什么操作
14 */
15 typedef enum {
16 LOGIN,
17 REGISTER
18 }USER_TYPE;
19
20 /*!
21 * @Author Dylan.
22 *
23 * Callbacl Block
24 */
25 typedef void(^connectSuccess)();
26 typedef void(^AuthenticateFailure)(id);
27
28 typedef void(^registerSuccess)();
29 typedef void(^registerFailure)(id);
30
31 @interface ADXMPPConn : NSObject <XMPPStreamDelegate>
32
33 /*!
34 * @Author Dylan.
35 *
36 * xmppStream
37 */
38 @property (nonatomic, strong) XMPPStream * xmppStream;
39
40 /*!
41 * @Author Dylan.
42 *
43 * Username, Password
44 */
45 @property (nonatomic, strong) NSString * userName;
46 @property (nonatomic, strong) NSString * passWord;
47
48 /*!
49 * @Author Dylan. UserType
50 */
51 @property (nonatomic) USER_TYPE USERTYPE;
52
53 /*!
54 * @Author Dylan.
55 *
56 * Methods
57 */
58 #pragma mark - Methods
59
60 /*!
61 * shareInstance
62 */
63 + (instancetype)shareInstance;
64
65 /*!
66 * setup xmppStream
67 */
68 - (void) setupXmppStream;
69
70 /*!
71 * on/off line
72 */
73 - (void) online;
74 - (void) offline;
75
76 /*!
77 * connection/register
78 */
79 - (BOOL)connectionWithUserName: (NSString *)userName
80 passWord: (NSString *)passWord
81 success: (connectSuccess)Success
82 failure: (AuthenticateFailure)Failure;
83
84 - (void)registerWithUserName: (NSString *)userName
85 passWord: (NSString *)passWord
86 success: (registerSuccess)Success
87 failure: (registerFailure)Failure;
88
89 @end
ADXMPPConn.m
1 //
2 // ADXMPPConn.m
3 // ADXMPP_BE
4 //
5 // Created by Dylan on 14-10-8.
6 // Copyright (c) 2014年 Dylan. All rights reserved.
7 //
8
9 #import "ADXMPPConn.h"
10
11 @interface ADXMPPConn ()
12
13 /*!
14 * @Author Dylan.
15 *
16 * Callback Block
17 */
18 @property (nonatomic, copy) connectSuccess connSuccess;
19 @property (nonatomic, copy) AuthenticateFailure authenFailure;
20
21 @property (nonatomic, copy) registerSuccess regisSuccess;
22 @property (nonatomic, copy) registerFailure regisFailure;
23
24 @end
25
26 // shareInstance
27 static ADXMPPConn * xmppConn;
28
29 @implementation ADXMPPConn
30
31 #pragma mark shareInstance
32 + (instancetype)shareInstance {
33 static dispatch_once_t onceToken;
34 dispatch_once(&onceToken, ^{
35 xmppConn = [[self alloc] init];
36 });
37
38 return xmppConn;
39 }
40
41 #pragma mark - Methods
42 - (void)setupXmppStream {
43 self.xmppStream = [[XMPPStream alloc] init];
44 [_xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
45 }
46
47 #pragma mark on/off line
48 - (void)online {
49 XMPPPresence * presence = [XMPPPresence presence];
50 [self.xmppStream sendElement:presence];
51 }
52
53 - (void)offline {
54 XMPPPresence * presence = [XMPPPresence presenceWithType:@"unavailable"];
55 [self.xmppStream sendElement:presence];
56 [self.xmppStream disconnect];
57 }
58
59 #pragma mark connection
60 - (BOOL)connectionWithUserName:(NSString *)userName passWord:(NSString *)passWord success:(connectSuccess)Success failure:(AuthenticateFailure)Failure {
61
62 // setup xmppStream
63 [self setupXmppStream];
64
65 // get username, password
66 self.userName = userName;
67 self.passWord = passWord;
68
69 // set callback block
70 self.connSuccess = Success;
71 self.authenFailure = Failure;
72
73 if ([self.xmppStream isConnected]) {
74 return YES;
75 }
76
77 if (userName == nil) {
78 return NO;
79 }
80
81 // setJID
82 [self.xmppStream setMyJID:[XMPPJID jidWithString:userName]];
83 [self.xmppStream setHostName:SERVER];
84
85 NSError * error = nil;
86 if (![self.xmppStream connectWithTimeout:30 error:&error]) {
87 NSLog(@"%@", [error localizedDescription]);
88 Failure(error);
89 return NO;
90 }
91
92 return YES;
93 }
94
95 - (void)registerWithUserName:(NSString *)userName passWord:(NSString *)passWord success:(registerSuccess)Success failure:(registerFailure)Failure {
96
97 // set user type
98 self.USERTYPE = REGISTER;
99
100 // set username, password
101 self.userName = [userName stringByAppendingString:DOMAINS];
102 self.passWord = passWord;
103
104 self.regisSuccess = Success;
105 self.regisFailure = Failure;
106
107 [self connectionWithUserName:self.userName passWord:passWord success:Success failure:Failure];
108 }
109
110 #pragma mark - delegateMethods
111 - (void)xmppStreamDidConnect:(XMPPStream *)sender {113
114 NSError * error = nil;
115
116 // kind of user type
117 if (self.USERTYPE == REGISTER) {
118
119 // registe
120 [self.xmppStream setMyJID:[XMPPJID jidWithString:self.userName]];
121 NSError * error = nil;
122 if (![self.xmppStream registerWithPassword:self.passWord error:&error]) {
123 self.regisFailure([error localizedDescription]);
124 }
125
126 } else {
127 // authenticate
128 [self.xmppStream authenticateWithPassword:self.passWord error:&error];
129 if (error != nil) {
130 self.authenFailure([error localizedDescription]);
131 }
132 }
133 }
134
135 // dis connect
136 - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error {
137 NSLog(@"%@", [error localizedDescription]);
138 }
139
140 // authenticate
141 - (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error {
142 self.authenFailure(error);
143 }
144
145 - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
146 // online
147 [self online];
148 self.connSuccess();
149 }
150
151 // regist
152 - (void)xmppStreamDidRegister:(XMPPStream *)sender {
153 self.regisSuccess();
154 }
155
156 - (void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error {
157 self.regisFailure(error);
158 }
159
160 @end
XMPP收发消息2
Message:
接着写
.h
1 /*! 2 * @Author Dylan. 3 * 4 * callback Block 5 */ 6 typedef void(^sendSuccess)(); 7 typedef void(^sendFailure)(id); 8 9 /*! 10 * sendMessageBy model 11 */ 12 - (void)sendMessage: (ADMessageModel *)message 13 sendSuccess: (sendSuccess)success 14 sendFailure: (sendFailure)failure; 15 16 /*! 17 * @Author Dylan. 18 * 19 * unRead Msg 20 */ 21 @property (nonatomic, strong) NSMutableDictionary * unReadMsg; 22 23 /*! 24 * @Author Dylan. 25 * 26 * new Msg 27 */ 28 @property (nonatomic, copy) void (^newMessage) (id); 29 30 31 @end
.m
1 #pragma mark - initData
2 - (void)initData {
3 // 可做数据持久化
4 self.unReadMsg = [NSMutableDictionary dictionary];
5 }
6
7 #pragma mark Methods
8 - (void)sendMessage: (ADMessageModel *)message
9 sendSuccess: (sendSuccess)success
10 sendFailure: (sendFailure)failure {
11
12 // set callback block
13 self.success = success;
14 self.failure = failure;
15
16 NSXMLElement * body = [NSXMLElement elementWithName:@"body"];
17 [body setStringValue:message.body];
18
19 //生成XML消息文档
20 NSXMLElement *mes = [NSXMLElement elementWithName:@"message"];
21 //消息类型
22 [mes addAttributeWithName:@"type" stringValue:@"chat"];
23 //发送给谁
24 [mes addAttributeWithName:@"to" stringValue:message.to];
25 //由谁发送
26 [mes addAttributeWithName:@"from" stringValue:message.from];
27 //组合
28 [mes addChild:body];
29 //发送消息
30 [[self xmppStream] sendElement:mes];
31 }
32
33 #pragma mark - delegeteMethods
34 - (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message {
35
36 NSString * body = [[message elementForName:@"body"] stringValue];
37 NSString * from = [[message attributeForName:@"from"] stringValue];
38
39 if (body != nil) {
40
41 NSMutableDictionary * msgDict = [NSMutableDictionary dictionary];
42 ADMessageModel * model = [[ADMessageModel alloc] init];
43 model.body = body;
44 model.from = from;
45 [msgDict setValue:model forKey:[ADCurrentTime getCurrentTime]];
46
47 if ([from isEqualToString:[[NSUserDefaults standardUserDefaults] stringForKey:CURRENT_CHAT]]) {
48
49 self.newMessage(msgDict);
50 } else {
51 // not current chat
52 if ([_unReadMsg.allKeys containsObject:from]) {
53 [_unReadMsg[from] addObject:model];
54 } else {
55 [_unReadMsg setValue:[NSMutableArray arrayWithObject:msgDict] forKey:from];
56 }
57 }
58
59 }
60 }
61
62 @end
XMPP好友列表3
// Roster
我们继续写 获取好友列表
.h
1 /*! 2 * @Author Dylan. 3 * 4 * Roster 5 */ 6 7 typedef void (^refreshRosterListFailure) (id); 8 typedef void (^Rosterlist) (id); 9 10 /*! 11 * @Author Dylan. 12 * 13 * request for roster list. IQ 14 */ 15 - (void)refreshRosterList: (Rosterlist)success 16 failure: (refreshRosterListFailure)failure; 17 @property (nonatomic, strong) NSMutableDictionary * rosterDict;
.m
1 #pragma mark - rosterList
2
3 - (void)initRosterlist {
4 self.rosterDict = [NSMutableDictionary dictionary];
5 }
6
7 - (void)refreshRosterList: (Rosterlist)success
8 failure: (refreshRosterListFailure)failure {
9
10 // call back
11 self.refreshSuccess = success;
12 self.refreshFailure = failure;
13
14 NSXMLElement * query = [NSXMLElement elementWithName:@"query" xmlns:@"jabber:iq:roster"];
15 NSXMLElement * iq = [NSXMLElement elementWithName:@"iq"];
16
17 XMPPJID * myJID = self.xmppStream.myJID;
18 [iq addAttributeWithName:@"from" stringValue:myJID.description];
19 [iq addAttributeWithName:@"to" stringValue:myJID.domain];
20 [iq addAttributeWithName:@"id" stringValue:@"123456"];
21 [iq addAttributeWithName:@"type" stringValue:@"get"];
22 [iq addChild:query];
23
24 [self.xmppStream sendElement:iq];
25 }
26
27 - (void)xmppStream:(XMPPStream *)sender didFailToSendIQ:(XMPPIQ *)iq error:(NSError *)error {
28 self.refreshFailure(error);
29 }
30
31 // get user list
32 - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq {
33
34 // kind of result
35 if ([@"result" isEqualToString:iq.type]) {
36 NSXMLElement * query = iq.childElement;
37
38 if ([@"query" isEqualToString:query.name]) {
39 NSArray * items = [query children];
40 for (NSXMLElement * item in items) {
41 NSString * jid = [item attributeStringValueForName:@"jid"];
42 XMPPJID * xmppJID = [XMPPJID jidWithString:jid];
43 [_rosterDict setValue:xmppJID forKey:jid];
44 }
45 }
46 // block
47 self.refreshSuccess(_rosterDict);
48 return YES;
49 }
50
51 NSLog(@"get iq error");
52 return NO;
53 }
54
55
56 @end
// 顺便写出在点m文件中我写的回掉Block 的属性
1 @interface ADXMPPConn () 2 3 /*! 4 * @Author Dylan. 5 * 6 * Call back Block 7 */ 8 @property (nonatomic, copy) connectSuccess connSuccess; 9 @property (nonatomic, copy) AuthenticateFailure authenFailure; 10 11 @property (nonatomic, copy) registerSuccess regisSuccess; 12 @property (nonatomic, copy) registerFailure regisFailure; 13 14 /*! 15 * call back block 16 */ 17 @property (nonatomic, copy) sendSuccess success; 18 @property (nonatomic, copy) sendFailure failure; 19 20 /*! 21 * call back block 22 */ 23 @property (nonatomic, copy) refreshRosterListFailure refreshFailure; 24 @property (nonatomic, copy) Rosterlist refreshSuccess; 25 26 @end
xmpp好友状态4
// 实现好友状态的获取 - 在线、离线 别的状态自己去写一下判断和回掉就好
.h
1 /*! 2 * @Author Dylan. 3 * 4 * Paresence 5 */ 6 typedef void (^userGoOnline) (NSString *); 7 typedef void (^userGoOffline) (NSString *); 8 9 - (void)refreshRosterPresence: (userGoOnline)online 10 offline: (userGoOffline)offline;
.m
1 #pragma mark presence
2 - (void)refreshRosterPresence: (userGoOnline)online
3 offline: (userGoOffline)offline {
4
5 self.rosterOnline = online;
6 self.rosterOffline = offline;
7 }
8
9 - (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence {
10
11 // get presence type
12 NSString * presenceType = [presence type];
13 NSString * userID = [[sender myJID] user];
14
15 NSString * presencrFromUser = [[presence from] user];
16 if (![presencrFromUser isEqualToString:userID]) {
17 if ([presenceType isEqualToString:@"available"]) {
18 self.rosterOnline(presencrFromUser);
19 } else if ([presenceType isEqualToString:@"unavailable"]) {
20 self.rosterOffline(presencrFromUser);
21 }
22 }
23 }
补上Block回掉申明
1 /*! 2 * call back block 3 */ 4 @property (nonatomic, copy) userGoOnline rosterOnline; 5 @property (nonatomic, copy) userGoOffline rosterOffline;
xmpp好友请求5
实现好友请求
.m
1 #pragma mark - rosterHandle
2
3 // initRoster
4 - (void)initRoster {
5 self.xmppRosterMemory = [[XMPPRosterMemoryStorage alloc] init];
6 self.xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:self.xmppRosterMemory];
7 [_xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];
8 [_xmppRoster activate:self.xmppStream];
9 }
10
11 - (void)addFriend: (NSString *)accountName {
12 [_xmppRoster addUser:[XMPPJID jidWithString:[accountName stringByAppendingString:DOMAINS]] withNickname:nil];
13 }
14
15 - (void)removeFriend: (NSString *)accountName {
16 [_xmppRoster removeUser:[XMPPJID jidWithString:[accountName stringByAppendingString:DOMAINS]]];
17 }
18
19 // call back
20 - (void)dealWithFriendAsk: (BOOL)isAgree
21 accountName: (NSString *)accountName {
22 XMPPJID * jid=[XMPPJID jidWithString:[NSString stringWithFormat:@"%@%@",accountName,DOMAINS]];
23 if(isAgree){
24 [self.xmppRoster acceptPresenceSubscriptionRequestFrom:jid andAddToRoster:NO];
25 }else{
26 [self.xmppRoster rejectPresenceSubscriptionRequestFrom:jid];
27 }
28
29 }
30
31 #pragma mark addFriendDelegateMethods
32 - (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence {
33
34 NSString *presenceFromUser =[NSString stringWithFormat:@"%@", [[presence from] user]];
35 if (self.acceptOrDenyFriend != nil) {
36 BOOL isAgree = self.acceptOrDenyFriend(presenceFromUser);
37 [self dealWithFriendAsk:isAgree accountName:presenceFromUser];
38 }
39 }
40
41 @end
.h
1 /*! 2 * @Author Dylan. 3 * 4 * addRoster. 5 */ 6 // if you want to deny or add friend. please call this block 7 @property (nonatomic, copy) BOOL (^acceptOrDenyFriend) (NSString *); 8 @property (nonatomic, strong) XMPPRoster * xmppRoster; 9 10 /*! 11 * @Author Dylan. Methods 12 */ 13 - (void)addFriend: (NSString *)accountName; 14 - (void)removeFriend: (NSString *)accountName;
XMPP教学小结1
到这里、 我们封装了XMPP 登录、 注册、 好友列表获取、 好友状态获取、 信息的收发、
应该去测试一下了 、 我这里把最简单的测试办法扔到这里、 大家可以看一下 。
1 //
2 // ADViewController.m
3 // ADXMPP_BE
4 //
5 // Created by Dylan on 14-10-8.
6 // Copyright (c) 2014年 Dylan. All rights reserved.
7 //
8
9 #import "ADViewController.h"
10 #import "ADMessageModel.h"
11
12 @interface ADViewController ()
13
14 @end
15
16 @implementation ADViewController
17
18 - (void)viewDidLoad
19 {
20 [super viewDidLoad];
21
22
23 // testLogin
24 [XMPPHANDLE connectionWithUserName:@"dylan@127.0.0.1" passWord:@"admin" success:^{
25 NSLog(@"success");
26
27 [XMPPHANDLE refreshRosterPresence:^(NSString * userID) {
28
29 NSLog(@"%@%@", userID, DOMAINS);
30 } offline:^(NSString * userID) {
31
32 NSLog(@"%@%@", userID, DOMAINS);
33 }];
34
35 [XMPPHANDLE refreshRosterList:^(id dict) {
36 NSLog(@"%@", dict);
37
38 } failure:^(id error) {
39 NSLog(@"%@", error);
40 }];
41
42 // testMsg
43 [[NSUserDefaults standardUserDefaults] setValue:@"alice@127.0.0.1/xueyulundeMacBook-Pro" forKey:CURRENT_CHAT];
44 [XMPPHANDLE setNewMessage:^(id dict) {
45 NSLog(@"%@", dict);
46 }];
47
48 ADMessageModel * model = [[ADMessageModel alloc] init];
49 model.from = [NSString stringWithFormat:@"%@", XMPPHANDLE.xmppStream.myJID];
50 model.to = [[NSUserDefaults standardUserDefaults] stringForKey:CURRENT_CHAT];
51 model.body = @"Hello";
52
53 [XMPPHANDLE sendMessage:model sendSuccess:^{
54
55 NSLog(@"send success");
56
57 } sendFailure:^(id error) {
58 NSLog(@"%@", error);
59 }];
60
61 } failure:^(id error) {
62 NSLog(@"error");
63 }];
64
65 // testRegis
66 // [XMPPHANDLE registerWithUserName:@"test" passWord:@"admin" success:^{
67 // NSLog(@"register success");
68 // } failure:^(id error) {
69 // NSLog(@"%@", error);
70 // }];
71 }
72
73 - (void)didReceiveMemoryWarning
74 {
75 [super didReceiveMemoryWarning];
76 }
77
78 @end
特别需要注意的是代码的执行先后顺序。
代理执行方法的先后顺序
保证自己的Block方法体可以被寻找到
