当前位置: 首页 > 图灵资讯 > 技术篇> iOS开发之使用XMPPFramework实现即时通信(二)

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

来源:图灵教育
时间:2023-05-23 09:24:10

iOS开发中使用XMPPFramework实现即时通信(1)只是本文的介绍。本博客为之前的微信增加了即时通信功能,主要用于XMPPFramework。本博客使用Spark进行测试。当然,Openfire服务器是必不可少的。这里不详细介绍Openfire的安装过程(在线教程仍然很多)。Openfire的安装只需要一个数据库的支持。本文使用MySql数据库。当然,这不是本文的重点。

废话少说,切入今天的话题。今天,我们应该加入以前的微信登录,获取朋友列表、聊天(发送文本、表达、图片、声音等功能)、最近的联系人等。在博客的开头,我们应该先来几张图片来介绍功能,然后给出核心代码的实现。

一、功能模块截图

1.登录并获取朋友名单

登录过程是用XMPPFramework连接Openfire的过程。如果用户已经登录,用户的JID和密码将从Userdefault中自动连接。如果用户未登录,则登录。XMPPFramework中的Roster还获得了朋友列表。操作截图如下:

iOS开发之使用XMPPFramework实现即时通信(二)_好友列表

2.朋友点击聊天页面。如果聊天时发送的图片或声音首先存储在服务器上,服务器将返回存储路径,然后将URL发送给接收器,接收器将下载
(1)如果是发送的文本,将文本转换为属性字符串,然后转换为NSData,最后将字符串转换为Message的Body。以下是Spark接收端的测试。截图如下:

iOS开发之使用XMPPFramework实现即时通信(二)_好友列表_02

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

iOS开发之使用XMPPFramework实现即时通信(二)_好友列表_03

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

iOS开发之使用XMPPFramework实现即时通信(二)_好友列表_04

二、代码实现部分

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

1.使用XMPPFramework前的准备,获取XMPStream和激活要使用的组件,并在Appdelegate中添加代码。以后用XMPStream的时候,要通过Appdelegate获得。以下代码是在Appdelegate.m中相关组件的初始化代码如下

(1)实例XMPPStreamm

//创建xmppstreamm创建 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,然后连接服务器和验证密码。如果认证成功,跳转到好友列表,然后将JID和Password存储在Userdefaults中,方便下次自动连接。以下代码是登录部分的代码(LoginViewController.m):

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

1 -(void) initXmpp 2 { 3     ///获取应用的xmpsteam(通过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         创建JID//1 7         XMPPJID *jid = [XMPPJID jidWithUser:self.userNameTextFiled.text domain:MY_DOMAIN resource:@"iPhone"]; 8          9         /2.在xmppsteam中添加JID         [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     else22     {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     else15     {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     //密码进入userdefaultt 7     NSUserDefaults *userDefult = [NSUserDefaults standardUserDefaults]; 8     [userDefult setObject:self.userNameTextFiled.text forKey:@"username"]; 9     [userDefult setObject:self.passwordTextFiled.text forKey:@"password"];10     11     ///设置在线状态122     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 *)error3 {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 && 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     //上下文2获得Roster     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])];4     //添加排序规则5     NSSortDescriptor * sortD = [NSSortDescriptor sortDescriptorWithKey:@"jidStr" ascending:YES];6     [request setSortDescriptors:@[sortD]];

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

1     //获得FRC2     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     }

爱上CoreData的IOS开发表视图。

IOS开发的微信聊天工具栏包装

实现iOS开发的微信聊天页面

今天的XMPPFramework先到这里,内容相当多。事实上,XMPPFramework中的组件使用方法是相似的。首先,初始化内存,然后进行相关配置,然后在XMPPStream中激活,最后如何使用。