基于XMPP协议的即时通信

iOS开发之使用XMPPFramework实现即时通信(二)

切入今天的正题。今天要给之前的微信加入登陆,获取好友列表,聊天(发送文字,表情,图片,声音等功能),最近联系人等。在博客的开头还是先来几张图来介绍一下功能,然后再给出核心代码的实现。

 

  一、功能模块截图

 

    1.登陆和获取好友列表

 

      登陆的过程就是连接用XMPPFramework连接Openfire的过程,如果用户登陆过,就从UserDefault里获取用户的JID和密码自动连接,如果用户没有登陆过则登陆。获取好友列表也是通过XMPPFramework中的Roster来获取的,运行截图如下:

 

 

 

    2.好友点击去就是聊天页面,聊天时如果是发送的图片或者声音,先存储到服务器上存储,服务器会返回存储路径然后再把URL发送给接收方,接收方再下载

 

      (1)如果是发送的文字,把文字转成属性字符串,然后再转成NSData,最后转成字符串放在Message的Body中进行发送,下面是用Spark做接收端做得测试,截图如下:

 

 

 

    (2)发送图片,把图片的存储路径发送给对方,让对方从服务器上下载。截图如下:

 

 

 

    (3)发送声音和图片一样都是发送URL,截图如下:

 

 

 

  二、代码实现部分

 

    上面的部分是允许的效果截图,从截图上是不难看出功能点的。图就先贴到这吧,下面给出核心代码的实现。

 

    1.使用XMPPFramework前的准备,获取XmppStream和激活要用的组件,在AppDelegate添加代码。以后要用xmppStream时,要通过AppDelegate获取。下面的代码是在AppDelegate.m中进行的相关组件的初始化,代码如下

 

      (1)实例化XMPPStream

 

    //创建xmppstream

    self.xmppStream = [[XMPPStream alloc]init];

 

 

      (2)创建重连组件,并在xmppStream中激活

 

1   //创建重写连接组件

2     xmppReconnect= [[XMPPReconnect alloc] init];

3     //使组件生效

4     [xmppReconnect activate:self.xmppStream];

 

 

      (3)创建message部分的内容,接受的消息我们保存在本地数据库中,我们要显示的时候是从数据库中获取的。在初始化消息组件的时候,要指定保存策略,一般可以选的是CoreData还是内存。指定完保存策略后实例化Message是要关联保存策略,之后也是需要在XMPPStream中进行激活的,最后要获取CoreData的上下文。代码如下:

 

复制代码

1     //创建消息保存策略(规则,规定)

2     messageStorage = [XMPPMessageArchivingCoreDataStorage
sharedInstance];

3     //用消息保存策略创建消息保存组件

4     xmppMessageArchiving = [[XMPPMessageArchiving
alloc]initWithMessageArchivingStorage:messageStorage];

5     //使组件生效

6     [xmppMessageArchiving activate:self.xmppStream];

7     //提取消息保存组件的coreData上下文

8     self.xmppManagedObjectContext =
messageStorage.mainThreadManagedObjectContext;

复制代码

 

 

      (4),初始化获取好友列表的相关组件并指定保存策略,和上面的代码步骤极为相似。这也能看出来在XMPPFramework中进行组件的初始化步骤是差不多的。下面我们设定自动获取花名册,代码如下:

 

复制代码

1     xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];

2     xmppRoster = [[XMPPRoster alloc]
initWithRosterStorage:xmppRosterStorage];

3     //自动获取用户列表

4     xmppRoster.autoFetchRoster = YES;

5     xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;

6     

7     [xmppRoster activate:self.xmppStream];

8     self.xmppRosterManagedObjectContext =
xmppRosterStorage.mainThreadManagedObjectContext;

复制代码

 

 

    2.登陆模块的实现

 

      登陆时就是用户输入JID和Password,然后连接服务器和验证密码,如果认证成功则跳转到好友列表才Controller,同时把JID和Password存储到UserDefaults中便于下次自动连接。下面的代码就是登陆部分的代码(LoginViewController.m):

 

      (1).通过应用代理获取XMPPStream,并注册回调,代码如下:

 

复制代码

 1 -(void) initXmpp

 2 {

 3     //获取应用的xmppSteam(通过Application中的单例获取)

 4     UIApplication *application = [UIApplication
sharedApplication];

 5     id delegate = [application delegate];

 6     self.xmppStream = [delegate xmppStream];

 7     

 8     //注册回调

 9     [self.xmppStream addDelegate:self
delegateQueue:dispatch_get_main_queue()];

10 }

复制代码

 

 

      (2).创建JID连接服务器

 

复制代码

 1 //连接服务器

 2 -(void) xmppConnect

 3 {

 4     if (![self.userNameTextFiled.text isEqualToString:@””] &&
self.userNameTextFiled.text != nil)

 5     {

 6         //1.创建JID

 7         XMPPJID *jid = [XMPPJID
jidWithUser:self.userNameTextFiled.text domain:MY_DOMAIN
resource:@”iPhone”];

 8         

 9         //2.把JID添加到xmppSteam中

10         [self.xmppStream setMyJID:jid];

11         

12         //连接服务器

13         NSError *error = nil;

14         [self.xmppStream connectWithTimeout:10 error:&error];

15         if (error)

16         {

17             NSLog(@”连接出错:%@”,[error localizedDescription]);

18         }

19 

20     }

21     else

22     {

23         UIAlertView *alter = [[UIAlertView alloc]
initWithTitle:@”提示” message:@”用户名不能为空” delegate:nil
cancelButtonTitle:@”取消” otherButtonTitles:nil];

24         [alter show];

25     }

26 }

复制代码

 

 

      (3).连接成后需要认证密码,代码如下:

 

复制代码

 1 //连接后的回调

 2 -(void)xmppStreamDidConnect:(XMPPStream *)sender

 3 {

 4     if (![self.passwordTextFiled.text isEqualToString:@””] &&
self.passwordTextFiled.text != nil)

 5     {

 6         //连接成功后认证用户名和密码

 7         NSError *error = nil;

 8         [self.xmppStream
authenticateWithPassword:self.passwordTextFiled.text error:&error];

 9         if (error)

10         {

11             NSLog(@”认证错误:%@”,[error localizedDescription]);

12         }

13     }

14     else

15     {

16         UIAlertView *alter = [[UIAlertView alloc]
initWithTitle:@”提示” message:@”密码不能为空” delegate:self
cancelButtonTitle:@”取消” otherButtonTitles:nil];

17         [alter show];

18     }

19 }

复制代码

 

 

      (4)密码认证成功后的回调

 

复制代码

 1 //认证成功后的回调

 2 -(void)xmppStreamDidAuthenticate:(XMPPStream *)sender

 3 {

 4     NSLog(@”登陆成功”);

 5     

 6     //密码进入userDefault

 7     NSUserDefaults *userDefult = [NSUserDefaults
standardUserDefaults];

 8     [userDefult setObject:self.userNameTextFiled.text
forKey:@”username”];

 9     [userDefult setObject:self.passwordTextFiled.text
forKey:@”password”];

10     

11     //设置在线状态

12     XMPPPresence * pre = [XMPPPresence presence];

13     [self.xmppStream sendElement:pre];

14     

15     UIStoryboard *storybard = [UIStoryboard
storyboardWithName:@”Main” bundle:[NSBundle mainBundle]];

16     UIViewController *viewController = [storybard
instantiateViewControllerWithIdentifier:@”mainController”];

17     [self presentViewController:viewController animated:YES
completion:^{

18     }];

19 }

复制代码

 

 

      (5)密码认证失败后的回调

 

1 //认证失败的回调

2 -(void)xmppStream:sender didNotAuthenticate:(DDXMLElement *)error

3 {

4     NSLog(@”认证失败”);

5 }

 

 

      (6),二次登陆自动连接代码:

 

复制代码

 1    // 如果已登录就直接填充密码登陆

 2     NSUserDefaults *userDefult = [NSUserDefaults
standardUserDefaults];

 3     

 4     NSString *userName = [userDefult objectForKey:@”username”];

 5     NSString *password = [userDefult objectForKey:@”password”];

 6     NSLog(@”%@,%@”,userName,password);

 7     if (userName != nil && password != nil && ![userName
isEqualToString:@””] && ![password isEqualToString:@””])

 8     {

 9         self.userNameTextFiled.text = userName;

10         self.passwordTextFiled.text = password;

11         [self xmppConnect];

12     }

复制代码

    

 

    3.获取好友列表的XMPPFramework的代码实现

 

      在获取用户列表的代码中就会用到我们之前注册的Roster的内容,因为我们在实例化Roster的时候指定的保存策略是用CoreData进行保存的,并且是自动获取好友列表。所以在获取好友列表的TableViewController中我们只需要通过CoreData来获取好友列表即可。下面将给出获取好友列表的核心代码:

 

      (1),获取Roster对应的上下文,用于获取存储在Roster相应实体中的数据

 

1     //获取Roster的上下文

2     UIApplication *application = [UIApplication sharedApplication];

3     id delegate = [application delegate];

4     self.xmppRosterManagedObjectContext = [delegate
xmppRosterManagedObjectContext];

      

 

      (2).获取FetchRequst对象,并指定CoreData实体类,之后添加排序规则,代码如下:

 

复制代码

1     //从CoreData中获取数据

2     //通过实体获取FetchRequest实体

3     NSFetchRequest *request = [[NSFetchRequest alloc]
initWithEntityName:NSStringFromClass([XMPPUserCoreDataStorageObject
class])];

betway必威体育平台,4     //添加排序规则

5     NSSortDescriptor * sortD = [NSSortDescriptor
sortDescriptorWithKey:@”jidStr” ascending:YES];

6     [request setSortDescriptors:@[sortD]];

复制代码

  

 

      (3).获取FetchedResultController并注册回调,用于自动刷新TableView,代码如下:

 

1     //获取FRC

2     self.fetchedResultsController = [[NSFetchedResultsController
alloc] initWithFetchRequest:request
managedObjectContext:self.xmppRosterManagedObjectContext
sectionNameKeyPath:nil cacheName:nil];

3     self.fetchedResultsController.delegate = self;

 

 

      (4)获取存储的内容

 

复制代码

1     

2     //获取内容

3     NSError * error;

4     ;

5     if (![self.fetchedResultsController performFetch:&error])

6     {

7         NSLog(@”%s  %@”,__FUNCTION__,[error
localizedDescription]);

8     }

http://www.bkjia.com/IOSjc/887782.htmlwww.bkjia.comtruehttp://www.bkjia.com/IOSjc/887782.htmlTechArticleiOS开发之使用XMPPFramework实现即时通信(二)
切入今天的正题。今天要给之前的微信加入登陆,获取好友列表,聊天(发送文字,表情,图片,…

betway必威体育平台 1betway必威体育平台 2betway必威体育平台 3betway必威体育平台 4betway必威体育平台 5

 

 

betway必威体育平台 6

betway必威体育平台 7

betway必威体育平台 8

betway必威体育平台 9

 

 

//  XMPPManager.h
//  InstantMessage
//
//  Created by ChenJungang on 14-1-3.
//  Copyright (c) 2014年 chenjungang. All rights reserved.
//

#import <Foundation/Foundation.h>
#import “XMPPFramework.h”

@class XMPPManager;
@class BuddyItem;
@class MessageItem;

@protocol XMPPManagerDelegate <NSObject>
//在XMPPManager中受到好友的状态信息,通过代理,传递好友列表页面
-(void)XMPPManager:(XMPPManager *)manager
didReceiveBuddyItem:(BuddyItem *)item;

//- (void)xmppManager:(XMPPManager *)manager
didReceiveNewMessageWithMessageItem:(MessageItem *)item;
@end

@interface XMPPManager :
NSObject<XMPPStreamDelegate,XMPPRosterDelegate>

@property(nonatomic,strong)XMPPStream*  xmppStream;//xmpp服务类
用于管理xmpp的基本操作; 连接服务器 验证登陆 注册 发送信息等
@property(nonatomic,strong)XMPPRoster*  xmppRoster;//xmpp好友列表类

@property(nonatomic,weak)id<XMPPManagerDelegate>delegate;

@property(nonatomic,copy)void(^receiveMessageBlock)(XMPPManager
*,MessageItem *);

+(XMPPManager* )defaultManager;//单例初始化方法

-(BOOL)connectToServer;//连接服务器
-(void)disConnectToserver;//断开服务器连接

-(void)xmppReceiveMessageWithCompletionHandler:(void(^)(XMPPManager
*,MessageItem *))messageBlock;

相关文章