#import "AppDelegate.h"
#import "XMPPFramework.h"
/*
* 在AppDelegate实现登录 1. 初始化XMPPStream
2. 连接到服务器[传一个JID]
3. 连接到服务成功后,再发送密码授权
4. 授权成功后,发送"在线" 消息
*/
@interface AppDelegate ()<XMPPStreamDelegate>{
XMPPStream *_xmppStream;
} // 1. 初始化XMPPStream
-(void)setupXMPPStream; // 2.连接到服务器
-(void)connectToHost; // 3.连接到服务成功后,再发送密码授权
-(void)sendPwdToHost; // 4.授权成功后,发送"在线" 消息
-(void)sendOnlineToHost;
@end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 程序一启动就连接到主机
[self connectToHost];
return YES;
} #pragma mark -私有方法
#pragma mark 初始化XMPPStream
-(void)setupXMPPStream{ _xmppStream = [[XMPPStream alloc] init]; // 设置代理
[_xmppStream addDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, )];
} #pragma mark 连接到服务器
-(void)connectToHost{
NSLog(@"开始连接到服务器");
if (!_xmppStream) {
[self setupXMPPStream];
} // 设置登录用户JID
//resource 标识用户登录的客户端 iphone android XMPPJID *myJID = [XMPPJID jidWithUser:@"wangwu" domain:@"teacher.local" resource:@"iphone" ];
_xmppStream.myJID = myJID; // 设置服务器域名
_xmppStream.hostName = @"teacher.local";//不仅可以是域名,还可是IP地址 // 设置端口 如果服务器端口是5222,可以省略
_xmppStream.hostPort = ; // 连接
NSError *err = nil;
if(![_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&err]){
NSLog(@"%@",err);
} } #pragma mark 连接到服务成功后,再发送密码授权
-(void)sendPwdToHost{
NSLog(@"再发送密码授权");
NSError *err = nil;
[_xmppStream authenticateWithPassword:@"" error:&err];
if (err) {
NSLog(@"%@",err);
}
} #pragma mark 授权成功后,发送"在线" 消息
-(void)sendOnlineToHost{ NSLog(@"发送 在线 消息");
XMPPPresence *presence = [XMPPPresence presence];
NSLog(@"%@",presence); [_xmppStream sendElement:presence]; }
#pragma mark -XMPPStream的代理
#pragma mark 与主机连接成功
-(void)xmppStreamDidConnect:(XMPPStream *)sender{
NSLog(@"与主机连接成功"); // 主机连接成功后,发送密码进行授权
[self sendPwdToHost];
}
#pragma mark 与主机断开连接
-(void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error{
// 如果有错误,代表连接失败
NSLog(@"与主机断开连接 %@",error); } #pragma mark 授权成功
-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
NSLog(@"授权成功"); [self sendOnlineToHost];
} #pragma mark 授权失败
-(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error{
NSLog(@"授权失败 %@",error);
} #pragma mark -公共方法
-(void)logout{
// 1." 发送 "离线" 消息"
XMPPPresence *offline = [XMPPPresence presenceWithType:@"unavailable"];
[_xmppStream sendElement:offline]; // 2. 与服务器断开连接
[_xmppStream disconnect];
} @end

封装好的XMPP工具(登录,注册,注销)

WCXMPPTool.h

#import <Foundation/Foundation.h>
#import "Singleton.h"
#import "XMPPFramework.h" typedef enum {
XMPPResultTypeLoginSuccess,//登录成功
XMPPResultTypeLoginFailure,//登录失败
XMPPResultTypeNetErr,//网络不给力
XMPPResultTypeRegisterSuccess,//注册成功
XMPPResultTypeRegisterFailure//注册失败
}XMPPResultType; typedef void (^XMPPResultBlock)(XMPPResultType type);// XMPP请求结果的block @interface WCXMPPTool : NSObject singleton_interface(WCXMPPTool); @property (nonatomic, strong)XMPPvCardTempModule *vCard;//电子名片 /**
* 注册标识 YES 注册 / NO 登录
*/
@property (nonatomic, assign,getter=isRegisterOperation) BOOL registerOperation;//注册操作 /**
* 用户注销 */
-(void)xmppUserlogout;
/**
* 用户登录
*/
-(void)xmppUserLogin:(XMPPResultBlock)resultBlock; /**
* 用户注册
*/
-(void)xmppUserRegister:(XMPPResultBlock)resultBlock;
@end

WCXMPPTool.m

#import "WCXMPPTool.h"

/*
* 在AppDelegate实现登录 1. 初始化XMPPStream
2. 连接到服务器[传一个JID]
3. 连接到服务成功后,再发送密码授权
4. 授权成功后,发送"在线" 消息
*/
@interface WCXMPPTool ()<XMPPStreamDelegate>{
XMPPStream *_xmppStream;
XMPPResultBlock _resultBlock; XMPPvCardCoreDataStorage *_vCardStorage;//电子名片的数据存储 XMPPvCardAvatarModule *_avatar;//头像模块
} // 1. 初始化XMPPStream
-(void)setupXMPPStream; // 2.连接到服务器
-(void)connectToHost; // 3.连接到服务成功后,再发送密码授权
-(void)sendPwdToHost; // 4.授权成功后,发送"在线" 消息
-(void)sendOnlineToHost;
@end @implementation WCXMPPTool singleton_implementation(WCXMPPTool) #pragma mark -私有方法
#pragma mark 初始化XMPPStream
-(void)setupXMPPStream{ _xmppStream = [[XMPPStream alloc] init]; #warning 每一个模块添加后都要激活
//添加电子名片模块
_vCardStorage = [XMPPvCardCoreDataStorage sharedInstance];
_vCard = [[XMPPvCardTempModule alloc] initWithvCardStorage:_vCardStorage]; //激活
[_vCard activate:_xmppStream]; //添加头像模块
_avatar = [[XMPPvCardAvatarModule alloc] initWithvCardTempModule:_vCard];
[_avatar activate:_xmppStream]; // 设置代理
[_xmppStream addDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, )];
} #pragma mark 连接到服务器
-(void)connectToHost{
WCLog(@"开始连接到服务器");
if (!_xmppStream) {
[self setupXMPPStream];
} // 设置登录用户JID
//resource 标识用户登录的客户端 iphone android // 从单例获取用户名
NSString *user = nil;
if (self.isRegisterOperation) {
user = [WCUserInfo sharedWCUserInfo].registerUser;
}else{
user = [WCUserInfo sharedWCUserInfo].user;
} XMPPJID *myJID = [XMPPJID jidWithUser:user domain:@"teacher.local" resource:@"iphone" ];
_xmppStream.myJID = myJID; // 设置服务器域名
_xmppStream.hostName = @"127.0.0.1";//不仅可以是域名,还可是IP地址 // 设置端口 如果服务器端口是5222,可以省略
_xmppStream.hostPort = ; // 连接
NSError *err = nil;
if(![_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&err]){
WCLog(@"%@",err);
} } #pragma mark 连接到服务成功后,再发送密码授权
-(void)sendPwdToHost{
WCLog(@"再发送密码授权");
NSError *err = nil; // 从单例里获取密码
NSString *pwd = [WCUserInfo sharedWCUserInfo].pwd; [_xmppStream authenticateWithPassword:pwd error:&err]; if (err) {
WCLog(@"%@",err);
}
} #pragma mark 授权成功后,发送"在线" 消息
-(void)sendOnlineToHost{ WCLog(@"发送 在线 消息");
XMPPPresence *presence = [XMPPPresence presence];
WCLog(@"%@",presence); [_xmppStream sendElement:presence]; }
#pragma mark -XMPPStream的代理
#pragma mark 与主机连接成功
-(void)xmppStreamDidConnect:(XMPPStream *)sender{
WCLog(@"与主机连接成功"); if (self.isRegisterOperation) {//注册操作,发送注册的密码
NSString *pwd = [WCUserInfo sharedWCUserInfo].registerPwd;
[_xmppStream registerWithPassword:pwd error:nil];
}else{//登录操作
// 主机连接成功后,发送密码进行授权
[self sendPwdToHost];
} }
#pragma mark 与主机断开连接
-(void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error{
// 如果有错误,代表连接失败 // 如果没有错误,表示正常的断开连接(人为断开连接) if(error && _resultBlock){
_resultBlock(XMPPResultTypeNetErr);
}
WCLog(@"与主机断开连接 %@",error); } #pragma mark 授权成功
-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
WCLog(@"授权成功"); [self sendOnlineToHost]; // 回调控制器登录成功
if(_resultBlock){
_resultBlock(XMPPResultTypeLoginSuccess);
} } #pragma mark 授权失败
-(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error{
WCLog(@"授权失败 %@",error); // 判断block有无值,再回调给登录控制器
if (_resultBlock) {
_resultBlock(XMPPResultTypeLoginFailure);
}
} #pragma mark 注册成功
-(void)xmppStreamDidRegister:(XMPPStream *)sender{
WCLog(@"注册成功");
if(_resultBlock){
_resultBlock(XMPPResultTypeRegisterSuccess);
} } #pragma mark 注册失败
-(void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error{ WCLog(@"注册失败 %@",error);
if(_resultBlock){
_resultBlock(XMPPResultTypeRegisterFailure);
} } #pragma mark -公共方法
-(void)xmppUserlogout{
// 1." 发送 "离线" 消息"
XMPPPresence *offline = [XMPPPresence presenceWithType:@"unavailable"];
[_xmppStream sendElement:offline]; // 2. 与服务器断开连接
[_xmppStream disconnect]; // 3. 回到登录界面
// UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Login" bundle:nil];
//
// self.window.rootViewController = storyboard.instantiateInitialViewController;
[UIStoryboard showInitialVCWithName:@"Login"]; //4.更新用户的登录状态
[WCUserInfo sharedWCUserInfo].loginStatus = NO;
[[WCUserInfo sharedWCUserInfo] saveUserInfoToSanbox]; } -(void)xmppUserLogin:(XMPPResultBlock)resultBlock{ // 先把block存起来
_resultBlock = resultBlock; // Domain=XMPPStreamErrorDomain Code=1 "Attempting to connect while already connected or connecting." UserInfo=0x7fd86bf06700 {NSLocalizedDescription=Attempting to connect while already connected or connecting.}
// 如果以前连接过服务,要断开
[_xmppStream disconnect]; // 连接主机 成功后发送登录密码
[self connectToHost];
} -(void)xmppUserRegister:(XMPPResultBlock)resultBlock{
// 先把block存起来
_resultBlock = resultBlock; // 如果以前连接过服务,要断开
[_xmppStream disconnect]; // 连接主机 成功后发送注册密码
[self connectToHost];
} @end

自动登录

AppDelegate.m

#import "AppDelegate.h"
#import "XMPPFramework.h"
#import "WCNavigationController.h"
#import "DDLog.h"
#import "DDTTYLogger.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //从沙盒的路径
NSString *path=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]; //打开XMPP的日志
[DDLog addLogger:[DDTTYLogger sharedInstance]]; //设置导航栏背景
// [WCNavigationController setupNavTheme]; //从沙盒里加载用户的数据单例
[[WCUserInfo sharedWCUserInfo] loadUserInfoFromSanbox]; //判断用户的登录状态,YES直接来到主界面
if([WCUserInfo sharedWCUserInfo].loginStatus){
UIStoryboard *storayobard=[UIStoryboard storyboardWithName:@"Main" bundle:nil];
self.window.rootViewController=storayobard.instantiateInitialViewController; //自动登录服务
[[WCXMPPTool sharedWCXMPPTool]xmppUserLogin:nil];
} return YES;
}
@end

登录方法

#import "WCBaseLoginViewController.h"
#import "AppDelegate.h" @implementation WCBaseLoginViewController - (void)login{
// 登录 /*
* 官方的登录实现 * 1.把用户名和密码放在WCUserInfo的单例 * 2.调用 AppDelegate的一个login 连接服务并登录
*/ //隐藏键盘
[self.view endEditing:YES]; // 登录之前给个提示 [MBProgressHUD showMessage:@"正在登录中..." toView:self.view]; [WCXMPPTool sharedWCXMPPTool].registerOperation = NO;
__weak typeof(self) selfVc = self; [[WCXMPPTool sharedWCXMPPTool] xmppUserLogin:^(XMPPResultType type) {
[selfVc handleResultType:type];
}];
} -(void)handleResultType:(XMPPResultType)type{
// 主线程刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view
];
switch (type) {
case XMPPResultTypeLoginSuccess:
NSLog(@"登录成功");
[self enterMainPage];
break;
case XMPPResultTypeLoginFailure:
NSLog(@"登录失败");
[MBProgressHUD showError:@"用户名或者密码不正确" toView:self.view];
break;
case XMPPResultTypeNetErr:
[MBProgressHUD showError:@"网络不给力" toView:self.view];
default:
break;
}
}); } -(void)enterMainPage{ // 更改用户的登录状态为YES
[WCUserInfo sharedWCUserInfo].loginStatus = YES; // 把用户登录成功的数据,保存到沙盒
[[WCUserInfo sharedWCUserInfo] saveUserInfoToSanbox]; // 隐藏模态窗口
[self dismissViewControllerAnimated:NO completion:nil]; // 登录成功来到主界面
// 此方法是在子线程补调用,所以在主线程刷新UI
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
self.view.window.rootViewController = storyboard.instantiateInitialViewController;
}

IOS XMPP(即时通讯的框架)的更多相关文章

  1. IOS 即时通讯的框架 配置环境

    一.了解XMPP 协议(标准)XMPP 即时通讯协议SGIP 短信网关协议 这手机发短信 移动支付和网页支付 0x23232[0,1] 0x23232 0x23232 0x23232 只有协议,必须会 ...

  2. XMPP即时通讯资料记录

    几天开始研究XMPP即时通讯的技术,来实现移动应用的计时聊天功能.记录下参考的博客地址,还挺详细的. http://blog.csdn.net/fhbystudy/article/details/16 ...

  3. iOS开发之XMPP即时通讯简单实现

    首先搭载服务器和数据库 搭载服务器我用的是openfire,数据库用的是mysql 这里推荐两个链接 配置mysql,用的是mysql workbench http://justsee.iteye.c ...

  4. xmpp即时通讯的笔记(摘抄)

    xmpp的使用: 即时通讯 instant messaging(IM) :  -->实时收发信息! 即时通讯相关软件: **QQ,MSN,GoogleTalk,AIM,Jabber(XMPP别名 ...

  5. iOS之即时通讯相关理解

    Socket: 1>Socket又称"套接字" 2>网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 3>应用程序通常通 ...

  6. iOS - IM 即时通讯

    1.即时通讯技术 即时通讯(IM:Instant Messaging):又称实时通讯,支持用户在线实时交谈,允许两人或多人使用网络实时的传递文字消息.文件.语音与视频交流. 即时通讯在开发中使用的场景 ...

  7. iOS:XMPP即时聊天知识

    XMPP即时聊天框架:XMPPFramework   XMPP The Extensible Messaging and Presence Protocol(可扩展通讯和表示协议). 基于XML XM ...

  8. XMPP即时通讯

    XMPP:XMPP是基于XML的点对点通讯协议,The Extensible Messaging and Presence Protocol(可扩展通讯和表示协议). XMPP可用于服务类实时通讯,表 ...

  9. iOS开发--即时通讯常用第三方库

    前言 自毕业到现在,从事iOS即时通讯开发已经1年半之久.主要负责Allure开发,目前已上架,可以在苹果商店搜素Allure.Allure模仿微信的交互和设计效果,已经实现微信的大部分功能. 在这里 ...

  10. XMPP即时通讯基础知识

    XMPP参考 一.定义 XMPP 是一种很类似于http协议的一种数据传输协议,它的过程就如同“解包装--〉包装”的过程,用户只需要明白它接受的类型,并理解它返回的类型,就可以很好的利用xmpp来进行 ...

随机推荐

  1. Django 用模板来节省公共代码,

          如果我们有一个后台网站,或者显示个人信息的网站 标题logo,边框等信息的代码都是固定的,只有部分区域是改变, 我们如果用Django来写html的话就会重复代码.这时候我们只要用模板的方 ...

  2. 关于Hall定理的学习

    基本定义 \(Hall\) 定理是二分图匹配的相关定理 用于判断二分图是否存在完美匹配 存在完美匹配的二分图即满足最大匹配数为 \(min(|X|,|Y|)\) 的二分图,也就是至少有一边的点全部被匹 ...

  3. 八段代码彻底掌握 Promise

    1.Promise的立即执行性 var p = new Promise(function(resolve, reject){ console.log("create a promise&qu ...

  4. 深入了解javascript的sort方法

    在javascript中,数组对象有一个有趣的方法 sort,它接收一个类型为函数的参数作为排序的依据.这意味着开发者只需要关注如何比较两个值的大小,而不用管“排序”这件事内部是如何实现的.不过了解一 ...

  5. Spring.Net---2、IoC/DI基本概念

    ---------------------------------------------------------------------------------- (1)IoC/DI的概念 IoC ...

  6. SpringBoot之整合MyBatis

    今天了解一下SpringBoot如何与我们最常用的ORM框架Mybatis整合. 一. 需要在pom.xml文件里加入mybatis的依赖 <dependency> <groupId ...

  7. HDOJ2037 今年暑假不AC (经典的贪心问题)

    Description “今年暑假不AC?” “是的.” “那你干什么呢?” “看世界杯呀,笨蛋!” “@#$%^&*%...” 确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会 ...

  8. h5 简单拖放

    最新的HTML5标准为所有的html元素规定了一个draggable属性,它表明了元素是否可以拖动,默认情况下,图像,链接,选中的文字是可以拖动的,因为他们的draggable属性被自动设置为true ...

  9. Arcgis GDB文件地理数据库、shapefile、coverage 和其他基于文件的数据源所支持的函数的完整列表

    函数 以下是文件地理数据库.shapefile.coverage 和其他基于文件的数据源所支持的函数的完整列表.个人地理数据库和 ArcSDE 地理数据库也支持这些函数,但这些数据源可能使用不同的语法 ...

  10. seacms 6.45 命令执行漏洞分析

    前言 这是一个比较老的漏洞了,不过漏洞原理还是挺有意思的. 正文 漏洞位于 search.php 文件中. 首先包含了 common.php, 这个文件里面做了一些初始化工作,其中最重要的是对提交参数 ...