上篇的博客iOS开发之使用XMPPFramework实现即时通信(一)只是本篇的引子,本篇博客就给之前的微信加上即时通讯的功能,主要是对XMPPFramework的使用。本篇博客中用到了Spark做测试,当然也少不了Openfire服务器,在这就不详述Openfire的安装过程了(网上的教程还是蛮多的),Openfire的安装仅需要一个数据库的支持,本篇是用的MySql数据库。当然这不是本篇的重点。

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

  一、功能模块截图

    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

    //创建xmppstreamself.xmppStream = [[XMPPStream alloc]init];

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

1   //创建重写连接组件
2     xmppReconnect= [[XMPPReconnect alloc] init];
3     //使组件生效
4     [xmppReconnect activate:self.xmppStream];

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

//创建消息保存策略(规则,规定)messageStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance];//用消息保存策略创建消息保存组件xmppMessageArchiving = [[XMPPMessageArchiving alloc]initWithMessageArchivingStorage:messageStorage];//使组件生效[xmppMessageArchiving activate:self.xmppStream];//提取消息保存组件的coreData上下文self.xmppManagedObjectContext = messageStorage.mainThreadManagedObjectContext;

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

xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];//自动获取用户列表xmppRoster.autoFetchRoster = YES;xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;[xmppRoster activate:self.xmppStream];self.xmppRosterManagedObjectContext = xmppRosterStorage.mainThreadManagedObjectContext;

    2.登陆模块的实现

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

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

-(void) initXmpp
{//获取应用的xmppSteam(通过Application中的单例获取)UIApplication *application = [UIApplication sharedApplication];id delegate = [application delegate];self.xmppStream = [delegate xmppStream];//注册回调[self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
}

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

//连接服务器
-(void) xmppConnect
{if (![self.userNameTextFiled.text isEqualToString:@""] && self.userNameTextFiled.text != nil){//1.创建JIDXMPPJID *jid = [XMPPJID jidWithUser:self.userNameTextFiled.text domain:MY_DOMAIN resource:@"iPhone"];//2.把JID添加到xmppSteam中[self.xmppStream setMyJID:jid];//连接服务器NSError *error = nil;[self.xmppStream connectWithTimeout:10 error:&error];if (error){NSLog(@"连接出错:%@",[error localizedDescription]);}}else{UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"提示" message:@"用户名不能为空" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];[alter show];}
}

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

//连接后的回调
-(void)xmppStreamDidConnect:(XMPPStream *)sender
{if (![self.passwordTextFiled.text isEqualToString:@""] && self.passwordTextFiled.text != nil){//连接成功后认证用户名和密码NSError *error = nil;[self.xmppStream authenticateWithPassword:self.passwordTextFiled.text error:&error];if (error){NSLog(@"认证错误:%@",[error localizedDescription]);}}else{UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"提示" message:@"密码不能为空" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:nil];[alter show];}
}

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

//认证成功后的回调
-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{NSLog(@"登陆成功");//密码进入userDefaultNSUserDefaults *userDefult = [NSUserDefaults standardUserDefaults];[userDefult setObject:self.userNameTextFiled.text forKey:@"username"];[userDefult setObject:self.passwordTextFiled.text forKey:@"password"];//设置在线状态XMPPPresence * pre = [XMPPPresence presence];[self.xmppStream sendElement:pre];UIStoryboard *storybard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];UIViewController *viewController = [storybard instantiateViewControllerWithIdentifier:@"mainController"];[self presentViewController:viewController animated:YES completion:^{}];
}

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

1 //认证失败的回调
2 -(void)xmppStream:sender didNotAuthenticate:(DDXMLElement *)error
3 {
4     NSLog(@"认证失败");
5 }

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

// 如果已登录就直接填充密码登陆NSUserDefaults *userDefult = [NSUserDefaults standardUserDefaults];NSString *userName = [userDefult objectForKey:@"username"];NSString *password = [userDefult objectForKey:@"password"];NSLog(@"%@,%@",userName,password);if (userName != nil && password != nil && ![userName isEqualToString:@""] && ![password isEqualToString:@""]){self.userNameTextFiled.text = userName;self.passwordTextFiled.text = password;[self xmppConnect];}

    

    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实体类,之后添加排序规则,代码如下:

//从CoreData中获取数据//通过实体获取FetchRequest实体NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([XMPPUserCoreDataStorageObject class])];//添加排序规则NSSortDescriptor * sortD = [NSSortDescriptor sortDescriptorWithKey:@"jidStr" ascending:YES];[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)获取存储的内容

//获取内容NSError * error;;if (![self.fetchedResultsController performFetch:&error]){NSLog(@"%s  %@",__FUNCTION__,[error localizedDescription]);}

 

  至于如何在TableView上显示FetchedResultController获取的数据,请参考之前的博客:IOS开发之表视图爱上CoreData。

  最近联系人的代码和历史表情的代码类似,请参考之前的博客:iOS开发之微信聊天工具栏的封装

  聊页面的实现请参考之前的博客:iOS开发之微信聊天页面实现

  

  今天的XMPPFramework就先到这儿吧,内容也挺多的了,其实XMPPFramework中的组件使用方法都差不多,首先第初始化内存,然后进行相关配置,在后就是在XMPPStream中激活,最后就是如何使用了。

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

  1. IOS- 即时通讯原理,使用XMPPFramework实现即时通信

    即时通讯(Instant Messenger,简称IM)软件多是基于TCP/IP和UDP进行通讯的,TCP/IP和UDP都是建立在更低层的IP协议上的两种通讯传输协议.前者是以数据流的形式,将传输数据 ...

  2. iOS开发之线程间的MachPort通信与子线程中的Notification转发

    如题,今天的博客我们就来记录一下iOS开发中使用MachPort来实现线程间的通信,然后使用该知识点来转发子线程中所发出的Notification.简单的说,MachPort的工作方式其实是将NSMa ...

  3. iOS开发之使用Git的基本使用(二)

    通过前文iOS开发之使用Git的基本使用(一)的学习,相信大家对如何将iOS项目通过Git传到GitHub账户上有了一个基本的了解,其过程是相对繁琐和容易出错的.本文将告诉大家借助工具来帮助我们实现这 ...

  4. (0041) iOS 开发之几家第三方即时通讯

    项目需要介入即时通讯,就对当前主流的IM 第三方服务商进行了自己的对比了解. 1.网易云信 2.融云 3.环信 4.leanCloud 5.阿里百川-云旺 6.ArrowIM 云丛网络 最终我选取了融 ...

  5. 芒果iOS开发人事面试问题及答案汇总二

    35.眼下你生活中最重要的是什么? 回答提示:对我来说,能在这个领域找到工作是最重要的,能在贵公司任职对我说最重要. 36.你为什么愿意到我们公司来工作? 回答提示:对于这个问题,你要格外小心,如果你 ...

  6. iOS开发-使用OC搭建自己的Socket 包括服务端和客服端

    iOS开发-使用OC搭建自己的Socket 包括服务端和客服端 前言 开发须知 客服端 服务端 两端测试 前言 iOS开发中需要使用到Socket通信的地方,socket分为UDP和TCP,这次分享的 ...

  7. 文顶顶iOS开发博客链接整理及部分项目源代码下载

    网上的iOS开发的教程很多,但是像cnblogs博主文顶顶的博客这样内容图文并茂,代码齐全,示例经典,原理也有阐述,覆盖面宽广,自成系统的系列教程却很难找.如果你是初学者,在学习了斯坦福iOS7公开课 ...

  8. iOS 开发之照片框架详解

    一. 概要 在 iOS 设备中,照片和视频是相当重要的一部分.最近刚好在制作一个自定义的 iOS 图片选择器,顺便整理一下 iOS 中对照片框架的使用方法.在 iOS 8 出现之前,开发者只能使用 A ...

  9. IOS开发 - UIWebView(用法全面介绍,含最全的JS交互)

    前两天我写了一套关于JS与OC交互的三种方法的文章,但是发现自己对UIWebView理解的还是比较浅,一直认为只能简单的当一个webView来使用,具体很多细节都忽略,如果想看我之前UIWebView ...

最新文章

  1. C语言实现汉诺塔问题
  2. Bash shell
  3. 图像色彩空间与应用转换
  4. 【每日一题】二分查找
  5. LeetCode--023--合并K个排序链表
  6. SQL Server 2012中的Contained Database尝试
  7. swift 简单语句 控制流语句
  8. Android manifest属性总结
  9. php - 冒泡排序
  10. preloadlazy load
  11. axure删除的页面怎么恢复_微信删除好友怎么找回?快速恢复,真的不难
  12. 习题1.29 (积分方法的优化---simpson规则)
  13. DeepID1 分析
  14. eclipse创建maven
  15. dockerfile文件名_第八章 Dockerfile文件解析(二)
  16. STC89C52单片机蜂鸣器介绍以及《孤勇者》歌曲代码示例
  17. 注册表知识与技巧大全
  18. 一位教授跟我说:线性代数应该这样学
  19. PopWindow:基本使用与自定义PopWindow
  20. Objective-C 信息传递模型 [ ] 发送消息

热门文章

  1. 在 CentOS7 安装 ELK【转】
  2. hide handkerchief(hdu2104)
  3. 计算机基础学习必看书籍汇总
  4. SEO小程:医院网站优化之如何分析竞争对手的网站
  5. C#读写文本文件小结
  6. 你是一个职业的页面重构工作者吗?
  7. Kettle连接HiveServer2配置和常见问题解决
  8. lombok使用中出现继承关系的对象时,出现的问题及解决办法
  9. uiautomatorviewer 双击闪退问题解决
  10. Server 2008 R2多用户远程桌面连接授权,解决120天过期问题