xmpp

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方法体可以被寻找到

原文地址:https://www.cnblogs.com/meakelra/p/4073759.html