![0612就业等多个文件企信通_第1页](http://file4.renrendoc.com/view/10881121c5ec085efe2a655c73cc223d/10881121c5ec085efe2a655c73cc223d1.gif)
![0612就业等多个文件企信通_第2页](http://file4.renrendoc.com/view/10881121c5ec085efe2a655c73cc223d/10881121c5ec085efe2a655c73cc223d2.gif)
![0612就业等多个文件企信通_第3页](http://file4.renrendoc.com/view/10881121c5ec085efe2a655c73cc223d/10881121c5ec085efe2a655c73cc223d3.gif)
![0612就业等多个文件企信通_第4页](http://file4.renrendoc.com/view/10881121c5ec085efe2a655c73cc223d/10881121c5ec085efe2a655c73cc223d4.gif)
![0612就业等多个文件企信通_第5页](http://file4.renrendoc.com/view/10881121c5ec085efe2a655c73cc223d/10881121c5ec085efe2a655c73cc223d5.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
XMPP应用项目—企信通讲师:Vincent_Guo企信通概述目标实现一款企业内部使用的通讯应用应用领域满足企业内部的即时通讯需求,为企业提供全方位的移动即时通讯解决方案功能列表(一期)用户登录、注册电子名片企业名册添加好友文本消息表情文字在线状态文件传输语音交流部门会议产品定位市场需求目前很多企业为了提高员工的工作效率以及防止公司内部资料泄密,会禁止员工在办公时间使用诸如腾讯QQ之类即时通讯软件但是即时通讯软件的即时性与便利性,的确能够有效地提升企业内部员工沟通的效率产品定位企信通定位企业级用户,为企业提供全方位的移动即时通讯解决方案在企业中,畅顺的沟通对生产效率、管理质量起到至关重要的作用。在异步通信已无法满足办公需求的形式下,好的即时沟通平台,能够帮助实现高效沟通企信通是针对这一市场需求开发的企业级即时通讯平台。企业员工可以轻松地通过服务器与企业其他组织架构的人员进行通讯,并采用丰富的沟通方式进行实时沟通。文本消息、文件传输、语音的形式满足不同办公环境下的沟通需求企信通着力于帮助企业员工提高工作效率,减少企业内部通讯费用,使团队和信息工作者进行更加高效的沟通开发平台移动平台:iOS6.0+服务器:Openfire
3.9.1数据库:MySQL
5.6开发工具:Xcode
5.0版本控制器:git
一期开发时间:5工作日开发计划第1天:项目搭建,用户登录&注册第2天:电子名片&企业名册第3天:添加好友&文本消息&表情文字第4天:发送图片及文件第5天:音频录制及压缩第6~8天:优化,测试工作内容分解迭代式开发新建项目1.
新建"企信通"项目,勾选git2.
导入XMPP框架文件3.
添加框架需要的依赖文件4.
设置设备运行方向,仅纵向5.
编译测试,有两条警告6.
将程序提交至本地代码库Storyboard规划系统由两个Storyboard构成Login.storyboard:负责实现用户登录及注册功能Main.storyboard:负责实现企信通的即时通讯主体功能,包括以下三个主要功能模块:企信通:人员之间的内部交流企业名册:企业通讯录我的名片:个人名片的信息设置文件夹约定及其他Lib:存放项目引用的第三方库、分类及工具等代码Login:存放用户登录注册相关文件IM:存放即时通讯主体功能文件,随着系统开发的进展,将进一步细化图片素材:鉴于开发周期,在一期开发中,暂时使用其他IM软件中的图片素材,如:微信、QQ等应用程序图标启动画面Main.StoryboardLogin.storyboard按钮图片的拉伸处理,以兼容iOS6.0由于图像切片功能仅在iOS7.0之后才能使用,为了保证应用程序能够兼容iOS6.0针对按钮图像拉伸,还需要用代码进行处理stretchableImageWithLeftCapWidthXMPP框架的基本应用//设置XMPPStream(void)setupStream;//销毁XMPPStream并注销已注册的扩展模块(void)teardownStream;//通知服务器器用户上线(void)goOnline;//通知服务器器用户下线(void)goOffline;//连接到服务器(void)connect;//与服务器断开连接(void)disconnect;XMPPStream的使用由于XMPPStream是基于myJID建立的长连接,因此在应用程序中应该仅被实例化一次(didFinishLaunchingWithOptions)如果程序视图多次实例化XMPPStream,应该终止程序运行,以提示程序员纠错XMPPStream除了负责设定应用程序的代理之外,还用于添加XMPP框架的扩展,例如电子名片、花名册、自动连接等当出现内存警告时,应用程序内部属性会被销毁,此时,应该在dealloc方法中,销毁并释放XMPPStream对象以及相关的扩展setupStream方法//0.方法被调用时,要求_xmppStream必须为nil,否则通过断言提示程序员,并终止程序运行!NSAssert(_xmppStream
==nil,@"视图多次实例化XMPPStream!");//1.实例化XMPPStream_xmppStream
=
[[XMPPStream
alloc]
init];//2.添加代理//由于所有网络请求都是做基于网络的数据处理,这些数据处理工作与界面UI无关。//因此可以让代理方法在其他线城中运行,从而提高程序的运行性能,避免出现应用程序阻塞的情况[_xmppStream
addDelegate:selfdelegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0)];//3.设置XMPP扩展模块//3.1
设置自动重新连接_xmppReconnect
=
[[XMPPReconnect
alloc]
init];//4.激活扩展模块//4.1
自动重新连接模块[_xmppReconnect
activate:_xmppStream];teardownStream方法//1.
取消XMPPStream代理[_xmppStream
removeDelegate:self];//2.
取消在setupStream方法中注册的所有模块//2.1
自动重连模块[_xmppReconnect
deactivate];//3.
断开连接[_xmppStream
disconnect];//4.
释放内存_xmppStream
=
nil;_xmppReconnect
=
nil;通知服务器上线和下线#pragma
mark
通知服务器用户上线(void)goOnline{//1.实例化一个”展现“,上线的报告,默认类型是"available"XMPPPresence
*presence=[XMPPPresence
presence];//2.发送Presence给服务器//服务器知道“我”上线后,只需要通知我的好友,而无需通知我,因此,此方法没有回调[_xmppStream
sendElement:presence];}#pragma
mark
通知服务器用户下线(void)goOffline{//1.实例化一个”展现“,下线的报告XMPPPresence
*presence
=
[XMPPPresence
presenceWithType:@"unavailable"];//2.发送Presence给服务器,通知服务器客户端下线[_xmppStream
sendElement:presence];}connect方法//1.如果当前XMPP长连接已经存在,则直接返回if
([_xmppStream
isConnected])
{return;}//2.指定用户名、主机(服务器),连接时不需要passwordNSString
*userName=[[LoginUser
sharedLoginUser]jidName];NSString
*hostName=[[LoginUser
sharedLoginUser]hostName];//判断hostName
&
userName是否存在内容,避免在初始调用时出现问题
if
([hostName
isEmptyString]||
[userName
isEmptyString]){return;}//3.设置XMPPStream的JID和主机[_xmppStream
setMyJID:[XMPPJID
jidWithString:userName]];[_xmppStream
setHostName:hostName];//4.开始连接[_xmppStream
connectWithTimeout:XMPPStreamTimeoutNone
error:nil];disconnect方法#pragma
mark
断开连接-(void)disconnect{//1.通知服务器下线[self
goOffline];//2.
XMPPStream断开连接
[_xmppStream
disconnect];}XMPP登录、注册示意图XMPPStreammyJIDhostNamehostName对应的服务器以myJID名义的长连接发送注册请求注册成功用户注册流程通知服务器上、下线发送验证请求验证成功用户登录流程Appdelegate-(void)loginToServer{//1.从文件中读取登录信息//2.登录到服务器}LoginController-(void)login{//1.将登录信息保存在本地一个//2.调用appdelegate的登文件录方}-(void)register文件
username:xxxpassword:xxxhostName:xxx登录流程建立连接代理方法#pragma
mark
连接完成-
(void)xmppStreamDidConnect:(XMPPStream
*)sender在此方法中,可以根据成员变量发送注册或验证请求//发送注册请求[_xmppStream
registerWithPassword:password
error:nil];//发送身份验证请求[_xmppStream
authenticateWithPassword:password
error:nil];身份验证代理方法#pragma
mark
身份验证成功-
(void)xmppStreamDidAuthenticate:(XMPPStream
*)sender通知服务器当前用户上线通知客户端用户登录成功#pragma
mark
密码错误,身份验证失败-
(void)xmppStream:(XMPPStream
*)senderdidNotAuthenticate:(DDXMLElement
*)error通知客户端用户身份验证失败注册用户代理方法#pragma
mark
注册成功-
(void)xmppStreamDidRegister:(XMPPStream
*)sender使用用户密码验证身份,从而触发登录成功后续操作#pragma
mark
注册失败(用户名已经存在)-
(void)xmppStream:(XMPPStream
*)senderdidNotRegister:(DDXMLElement
*)error通知客户端用户注册失败用户登录状态变化的处理UIStoryboard*storyboard
=
nil;if
(isUserLogon)
{//显示Main.storyboardstoryboard
=
[UIStoryboard
storyboardWithName:@"Main"
bundle:nil];}
else
{//显示Login.sotryboardstoryboard
=
[UIStoryboard
storyboardWithName:@"Login"
bundle:nil];}dispatch_async(dispatch_get_main_queue(),
^{//把Storyboard的初始视图控制器设置为window的rootViewController[self.window
setRootViewController:storyboard.instantiateInitialViewController];if
(!self.window.isKeyWindow){[self.window
makeKeyAndVisible];}});自动重新连接如果出现意外断线,XMPPReconnect会自动重新连接到XMPP服务器xmppReconnect
=
[[XMPPReconnect
alloc]
init];[_xmppReconnect
activate:xmppStream];电子名片——vCardvCard(或称做Versitcard)最早是由Versit联盟于1995年提出的,当时联盟成员包括苹果公司,AT&T科技(后来的朗讯),IBM及西门子。在
1996年十二月,格式的拥有权移至因特网邮件联盟(IMC),此联盟是由一些关注因特网电子邮件的公司所组成vCard标准的2.1版被电子邮件客户端广泛支持。3.0版是一个包含在RFC2425和RFC
2426中的IETF标准跟踪提案。vCard的常用文件扩展名是.vcf不同的程序对vCard标准实现亦不同。Mac
OS
X中的Address
Book允许把所有联系人导出到一个vcf文件,而Microsoft
Outlook只能每人一个文件vCard是电子名片的文件格式标准,一般附加在电子邮件之后,但也可以用于其它场合(如在因特网上相互交换)XMPP中电子名片的使用1.
XEP-0054提供了一种机制,可以通过XMPP发送电子名片2.
要使用个人名片首先需要在XMPPFramework.h中启用电子名片的扩展头文件:#import
"XMPPvCardCoreDataStorage.h"#import
"XMPPvCardTempModule.h"3.
定义属性及成员变量4.
为XMPPSteam添加电子名片扩展5.
在需要时使用电子名片定义电子名片属性及成员变量1.
在.h文件中添加如下定义//全局电子名片模块@property
(strong,
nonatomic,
readonly)
XMPPvCardTempModule*xmppvCardModule;2.
在.m中添加如下成员变量//电子名片数据存储模块XMPPvCardCoreDataStorage
*_xmppvCardStorage;为XMPPSteam添加电子名片扩展//实例化电子名片模块xmppvCardStorage
=
[XMPPvCardCoreDataStorage
sharedInstance];_xmppvCardModule
=
[[XMPPvCardTempModulealloc]initWithvCardStorage:_xmppvCardStorage];//激活电子名片模块[_xmppvCardModule
activate:_xmppStream];初次运行会自动生成一个SQLite数据库文件电子名片的使用#import
"XMPPvCardTemp.h”XMPPvCardTemp
*myCard
=
[[[selfappDelegate]
xmppvCardModule]myvCardTemp];//判断是否存在电子名片if
(myCard
==
nil)
{myCard
=
[XMPPvCardTemp
vCardTemp];myCard.nickname
=
[[LoginUser
sharedLoginUser]
userName];myCard.jid
=
[XMPPJID
jidWithString:[LoginUser
sharedLoginUser].myJIDName];[[self
appDelegate]
saveMyCard:myCard];}备注:XMPP框架中没有实现电话和电子邮件的方法,实例中使用note作为电话,mailer作为电子邮件使用XMPP中花名册的使用1.
要使用花名册首先需要在XMPPFramework.h中启用电子名片的扩展头文件:#import
"XMPPRoster.h"#import
"XMPPRosterCoreDataStorage.h"2.
定义属性及成员变量3.
为XMPPSteam添加花名册扩展4.
设置花名册代理5.
在需要时使用花名册定义花名册属性及成员变量在.h文件中添加如下定义//全局花名册模块@property
(strong,
nonatomic,
readonly)
XMPPRoster
*xmppRoster;//全局花名册数据存储模块@property
(strong,
nonatomic,
readonly)
XMPPRosterCoreDataStorage*xmppRosterStorage;为XMPPSteam添加花名册扩展//实例化花名册模块_xmppRosterStorage
=
[[XMPPRosterCoreDataStorage
alloc]
init];_xmppRoster
=
[[XMPPRoster
alloc]
initWithRosterStorage:_xmppRosterStorage];//*
设置花名册属性[_xmppRoster
setAutoFetchRoster:YES];[_xmppRoster
setAutoAcceptKnownPresenceSubscriptionRequests:YES];//激活花名册模块[_xmppRoster
activate:_xmppStream];//添加代理[_xmppRoster
addDelegate:selfdelegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0)];初次运行会自动生成一个SQLite数据库文件花名册的使用导入CoreData框架使用NSFetchedResultsController(抓取结果控制器)可以有效地管理从Core
Data抓取返回的数据结果,并为UITableView对象提供数据UITableView的数据源方法#pragmamark
表格分组数量return
[_fetchedResultsController
sections].count;#pragma
mark每个分组中的表格行数NSArray
*sectionData=
[_fetchedResultsControllersections];if
(section
<
sectionData.count)
{id
<NSFetchedResultsSectionInfo>
sectionInfo
=
sectionData[section];return
[sectionInfo
numberOfObjects];}return
0;#pragma
mark单元格(行)对象XMPPUserCoreDataStorageObject
*user
=
[_fetchedResultsController
objectAtIndexPath:indexPath];cell.textLabel.text
=
user.displayName;设置抓取结果控制器(1)//1.如果要针对CoreData做数据访问,无论怎么包装,都离不开NSManagedObjectContext//实例化NSManagedObjectContextNSManagedObjectContext
*context
=
[[xmppDelegatexmppRosterStorage]mainThreadManagedObjectContext];//2.实例化NSFetchRequest
NSFetchRequest
*request=[NSFetchRequestfetchRequestWithEntityName:@"XMPPUserCoreDataStorageObject"];//3.实例化一个排序NSSortDescriptor
*sort1
=
[NSSortDescriptor
sortDescriptorWithKey:@"jidStr"
ascending:YES];[request
setSortDescriptors:@[sort1]];//4.实例化_fetchedResultsController_fetchedResultsController
=
[[NSFetchedResultsController
alloc]initWithFetchRequest:requestmanagedObjectContext:context
sectionNameKeyPath:@"sectionNum"
cacheName:nil];设置抓取结果控制器(2)//5.设置代理[_fetchedResultsController
setDelegate:self];//6.查询数据NSError
*error
=
nil;if
(![_fetchedResultsController
performFetch:&error])
{NSLog(@"%@",
error.localizedDescription);}#pragma
mark-NSFetchedResults控制器代理方法
[self.tableView
reloadData];添加&删除好友在XMPP框架中提供的添加好友的机制是一种订阅(Subscription)机制,类似于微博中的关注,即A可以添加B为好友,但是B不一定要添加A为好友如果要实现双向添加和删除,可以将xmppRoster的autoAcceptKnownPresenceSubscriptionRequests属性设置为YES从客户端发送添加好友请求//判断是否已经是好友[[xmppDelegate
xmppRosterStorage]
userExistsWithJID:jidxmppStream:[xmppDelegate
xmppStream]];//发送好友订阅请求[[xmppDelegate
xmppRoster]
subscribePresenceToUser:jid];从客户端接收添加好友请求-
(void)xmppStream:(XMPPStream
*)sender
didReceivePresence:(XMPPPresence
*)presence{//1.取得好友当前类型(状态)NSString
*presenceType
=
[presence
type];//2.如果是用户订阅,则添加用户if
([presenceType
isEqualToString:@"subscribe"])
{//接收好友订阅请求[_xmppRoster
acceptPresenceSubscriptionRequestFrom:[presence
from]andAddToRoster:YES];}}删除好友[[xmppDelegate
xmppRoster]
removeUser:user.jid];用户状态XMPPUserCoreDataStorageObject中的sectionNum“0”-在线“1”-离开“2”-离线使用表格分组显示用户在线状态NSArray
*sections
=
_fetchedResultsController.sections;if
(section
<
sections.count)
{id
<NSFetchedResultsSectionInfo>
info
=
sections[section];NSInteger
state
=
[[info
name]
integerValue];switch
(state)
{
case
0:return
@"在线";break;case
1:return
@"离开";break;case
2:return
@"下线";break;}}return
@"未知";用户头像——XMPPvCardAvatarModule-
(UIImage
*)loadPhotoForUser:(XMPPUserCoreDataStorageObject
*)user{//判断好友数据表中是否存在用户头像if
(user.photo)
{//如果存在直接返回return
user.photo;}//如果不存在,从用户名片中获取NSData
*photoData
=
[[xmppDelegate
xmppvCardAvatarModule]
photoDataForJID:user.jid];if
(photoData)
{return
[UIImage
imageWithData:photoData];}return
[UIImage
imageNamed:@"DefaultProfileHead"];}后台支持#if
!TARGET_IPHONE_SIMULATOR[_xmppStream
setEnableBackgroundingOnSocket:YES];#endif实体能力(XEP-0115)实体能力用于广播和动态查询客户端、设备或通用实体的能力。为了最小化网络冲击,传输机制采用标准的XMPP出席信息广播(从而防止和服务发现数据相关的数据轮询的需要),能力信息可被缓存在单个会话中也可以贯穿多个会话,并且格式已经尽可能保持最小对于一个XMPP应用程序,经常需要(通常但不一定是一个客户端)根据从另一个应用收到的出席信息所了解到的能力采取不同的动作。例如:根据其他实体的能力显示不同系列的图标不发送XHTML-IM或者其他富文本给只支持纯文本的客户端比如手机只有当客户端支持Jingle和Jingle
RTP
Sessions
时,才允许VoIP的初始化如果另一个用户客户端不支持SI
File
Transfer,那么不显示“发送文件”按钮基于声明的订阅者兴趣,过滤Publish-Subscribe通知准备工作1——聊天界面布局搭建利用自动布局设置文本输入框针对底部的三个约束利用通知中心监听键盘变化情况[[NSNotificationCenter
defaultCenter]
addObserver:selfselector:@selector(keyboardStateChanged:)name:UIKeyboardWillChangeFrameNotification
object:nil];用户键盘变化时,通过更改约束,调整用户界面//1.
获取用户信息NSDictionary
*info
=
[notification
userInfo];//2.
取出键盘属性//2.1
键盘所占区域CGRect
rect
=
[[info
objectForKey:UIKeyboardFrameEndUserInfoKey]
CGRectValue];//2.2
键盘动画时长CGFloat
duration
=
[[info
objectForKey:UIKeyboardAnimationDurationUserInfoKey]floatValue];//2.3
取出屏幕区域CGRect
screenRect
=
[UIScreen
mainScreen].bounds;//3.
根据区域的y值判断键盘是显示还是隐藏if
(rect.origin.y
==
screenRect.size.height)
{//3.1
隐藏键盘}
else
{//3.2
显示键盘(216,252)}//4.
动画更新布局[UIView
animateWithDuration:durationanimations:^{[self.view
layoutIfNeeded];}];文本消息聊天-
(void)xmppStream:(XMPPStream
*)senderdidReceiveMessage:(XMPPMessage
*)message代理方法中如果message的isChatMessage属性为YES,表示接收到的消息是聊天消息message消息格式示例<message
xmlns="jabber:client"
to="lisi@liufan9-mac.local"
type="chat"
id="E326027C-C1C8-48F5-8E2E-FCA24A67F0E0"
from="liufan4@liufan9-mac.local/liufan9-mac"><body>hi</body><html
xmlns="
"><body
xmlns="
"
style="background-color:#e9e9e9;color:#000000;"><span
style="font-family:
'Helvetica';font-size:12px;">hi</span></body></html><x
xmlns="jabber:x:event"><composing/></x><active
xmlns="
"/></message>消息数据处理——XEP-0136激活XMPPMessageArchiving和XMPPMessageArchivingCoreDataStorage消息归档模块实例化查询结果控制器//1.获取数据管理上下文//2.
实例化NSFetcheRequest@"XMPPMessageArchiving_Message_CoreDataObject"];//3.
设置查询条件[request
setPredicate:[NSPredicate
predicateWithFormat:@"streamBareJidStr
='lisi@liufan9-mac.local'
AND
bareJidStr
=
'liufan4@liufan9-mac.local'"]];//4.
设置排序//5.实例化查询控制器//6.
设置代理//7.
启动查询NSError
*error
=
nil;if
(![_fetchedResultsController
performFetch:&error]){
NSLog(@"查询错误:%@",error.localizedDescription);}数据源方法#pragma
mark
数据行数(NSInteger)tableView:(UITableView
*)tableView
numberOfRowsInSection:(NSInteger)section{id<NSFetchedResultsSectionInfo>
info
=
_fetchedResultsController.sections[0];return
[info
numberOfObjects];}#pragma
mark
表格行(UITableViewCell
*)tableView:(UITableView
*)tableView
cellForRowAtIndexPath:(NSIndexPath
*)indexPath{static
NSString
*FromID
=
@"ChatFromCell";UITableViewCell
*cell
=
[tableView
dequeueReusableCellWithIdentifier:FromID
forIndexPath:indexPath];XMPPMessageArchiving_Message_CoreDataObject
*message
=
[_fetchedResultsControllerobjectAtIndexPath:indexPath];cell.textLabel.text
=
message.body;return
cell;}发送消息#pragma
mark-UITextField代理方法-
(BOOL)textFieldShouldReturn:(UITextField
*)textField{NSString
*str
=
[textField.text
trimString];XMPPMessage
*msg
=
[XMPPMessage
messageWithType:@"chat"
to:[XMPPJIDjidWithString:@”zhangsan.local"]];[msg
addBody:str];NSLog(@"%@",
msg);[[xmppDelegate
xmppStream]
sendElement:msg];return
YES;}滚动到表格末尾//计算表格行数id
<NSFetchedResultsSectionInfo>
info
=
_fetchedResultsController.sections[0];NSIndexPath
*indexPath=
[NSIndexPath
indexPathForRow:([info
numberOfObjects]-1)
inSection:0];[self.tableView
selectRowAtIndexPath:indexPath
animated:YESscrollPosition:UITableViewScrollPositionBottom];表情文字的输入在iOS中,表情文字是通过Unicode字符实现的Unicode(中文:万国码、国际码、统一码、单一码)是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字Unicode伴随着通用字符集的标准而发展,同时也以书本的形式对外发表。Unicode至今仍在不断增修,每个新版本都加入更多新的字符,目前最新的版本为第六版,已收入了超过十万个字符。Unicode涵盖的数据除了视觉上的字形、编码方法、标准的字符编码外,还包含了字符特性,如大小写字母Unicode备受认可,并广泛地应用于电脑软件的国际化与本地化过程。有很多新科技,如可扩展置标语言、Java编程语言以及现代的操作系统,都采用Unicode编码化时的约束代码——直接修改约束优化键盘变大/1.获小取键盘的目标区域NSDictionary
*info
=
notification.userInfo;CGRect
rect
=
[info[UIKeyboardFrameEndUserInfoKey]
CGRectValue];CGFloat
duration
=
[info[UIKeyboardAnimationDurationUserInfoKey]
floatValue];//2.根据rect的orgion.y可以判断键盘是开启还是关闭if
(rect.origin.y
==
[UIScreen
mainScreen].bounds.size.height)
{_noInputTextConstraint.constant
=
0.0f;}
else
{_noInputTextConstraint.constant
=
rect.size.height;}//用自动布局系统实现动画,调整位置[UIView
animateWithDuration:duration
animations:^{[self.view
layoutIfNeeded];}
completion:^(BOOL
finished)
{[self
scrollToTableBottom];}];自定义视图将文字输入处理部分代码抽离自定义InputToolView
输入工具视图完成按钮点击切换代码自定义EmoteSelectView实现表情选择功能表情符号的参照地址:预定义表情字符数组static
unichar
emotechars[28]
={0xe415,
0xe056,
0xe057,
0xe414,
0xe405,
0xe106,
0xe418,0xe417,
0xe40d,
0xe40a,
0xe404,
0xe105,
0xe409,
0xe40e,0xe402,
0xe108,
0xe403,
0xe058,
0xe407,
0xe401,
0xe416,0xe40c,
0xe406,
0xe413,
0xe411,
0xe412,
0xe410,
0xe059,};XMPP中的文件传输XEP-0096:
File
Transfer
这是传输文件的统一接口,客户端之间用它来协商到底采用那种具体的传输方式,包括以下三种:XEP-0047:
In-Band
ByteStreams
带内字节流,这个协议实际上用于小数据量传输,只是它用的字节流传输,所以也顺便说一下。带内,也就是夹带在XML流中,通过XMPP服务器中转传输。具体用法是把数据用base64编码放在XML流中传给对方。这个办法不好,base64编码效率很低,而且所有数据必须由服务器中转(字符串格式的数据中转)XEP-0066:
Out
of
Band
Data
带外字节流,带内不行就走带外,也就是不经过XMPP服务器。这个用法是在发起传输的客户端临时建立一个http服务(当然也可以是别的服务),把自己的IP和端口(通过XMPP消息)告诉接收方,让对方直接来下载。这个方法有一个问题,发送一方必须是公网IP,否则对方无法访问。注:目前Pandion,Linq支持这个XEPXEP-0065:
SOCKS5
Bytestreams
SOCKS5字节流,使用SOCKS5传输文件,有直连式和代理传输两种方式。发送方把预定的IP和端口(通过XMPP消息)告诉接收方。如果双方都在公网,采用SOCKS直接传输。如果任何一方在内网,经过SOCKS5代理服务器传输,发送方把代理服务器的IP和端口告诉给接收方。这里的SOCKS5代理服务器和通用的代理服务器稍有差别,因为它需要通过发送方提出的一个sessionID由XMPP服务器通知SOCKS5代理服务器把双方的SOCKS
通道连通,也就是激活。注:目前Psi,Linq支持这个XEPBase64Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到直接使用字节流传输//发送数据XMPPMessage*msg
=
[XMPPMessagemessageWithType:@"img"
to:_bareJid];NSString
*str
=
[_sendData
base64Encoding];NSXMLElement
*bodyElement=
[NSXMLElement
elementWithName:@"imgData"
stringValue:str];[msg
addChild:bodyElement];//接收数据NSString
*imageString=
[[message
elementForName:@"imgData"]
stringValue];if
(imageString)
{NSData
*data
=
[[NSData
alloc]
initWithBase64EncodedString:imageStringoptions:NSDataBase64DecodingIgnoreUnknownCharacters];//将照片写入相册UIImage
*image
=
[UIImage
imageWithData:data];UIImageWriteToSavedPhotosAlbum(image,
nil,
nil,
nil);}TURNSocket——XEP65要使用服务器设置中,增加如下属性:xy.externalip//创建socket准备接收数据if
([TURNSocket
isNewStartTURNRequest:iq])
{TURNSocket
*socket
=
[[TURNSocket
alloc]
initWithStream:sender
ingTURNRequest:iq];[_turnSockets
addObject:socket];[socket
startWithDelegate:self
delegateQueue:dispatch_get_main_queue()];}接收成功代理方法NSMutableData
*data
=
[NSMutableData
data];
[socket
readDataToData:data
withTimeout:60.0f
tag:0];[data
writeToFile:path
atomically:YES];[_turnSockets
removeObject:sender];[socket
disconnectAfterWriting];使用jid建立socket连接方法-
(void)connectViaXEP65:(XMPPJID*)jid{if(jid
==
nil)
return;NSLog(@"Attempting
TURN
connection
to
%@",
jid);TURNSocket
*turnSocket
=
[[TURNSocket
alloc]
initWithStream:_xmppStream
toJID:jid];[_turnSockets
addObject:turnSocket];[turnSocket
startWithDelegate:self
delegateQueue:dispatch_get_main_queue()];}其他——判断IQ是否为SI请求-
(BOOL)isSIRequest:(XMPPIQ
*)iq{NSXMLElement
*si
=
[iq
elementForName:@"si"
xmlns:@""];NSString
*uuid
=
[[si
attributeForName:@"id"]stringValue];if(si
&&uuid
){return
YES;}return
NO;}界面小结企信通所有发生过联系的联系人聊天记录,最近聊天的内容显示在最上面单击每一条记录,可以进入与该联
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 15个课程设计曲线
- 供热工程的课程设计
- 管乐合奏教学课程设计
- 2024年紫外分析仪项目合作计划书
- 课程设计国贸
- led课程设计目录
- 2024年粉质仪项目发展计划
- html课程设计题目
- 2024年个人向个人借款合同格式范文(二篇)
- 2024年会计上半年工作总结简单版(四篇)
- DB61-T 1530-2022机组式凹版印刷机检验规程
- 中职职高信息技术专业《计算机组装与维护》课件
- 历史是什么课件
- 黄河流域生态保护与高质量发展课件
- 公园道路规范
- 《大青树下的小学》-完整版课件
- 蛇咬伤的救治护理 课件
- 数学低年级教研计划
- 监理平行检查记录表(共9)
- 【精品主题班会】高一家长会课件(共37张PPT)
- 2022版新修订道德与法治课程标准的解读与梳理培训课件
评论
0/150
提交评论