#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. Python——基本的方法

    格式化 我们经常会输出类似'亲爱的xxx你好!你xx月的话费是xx,余额是xx'之类的字符串,而xxx的内容都是根据变量变化的,所以,需要一种简便的格式化字符串的方式 >>> 'He ...

  2. Centos 7 ip地址

    vim /etc/sysconfig/network-scripts/ifcfg-ens33 HWADDR="00:15:5D:07:F1:02" TYPE="Ether ...

  3. SQLServer 触发器入门

    阅读目录 一:触发器的优点 二:触发器的作用 三:触发器的分类 四:触发器的工作原理 五:创建触发器 六:管理触发器 概念:   触发器(trigger)是SQL server 提供给程序员和数据分析 ...

  4. Hadoop源码学习笔记(6)——从ls命令一路解剖

    Hadoop源码学习笔记(6) ——从ls命令一路解剖 Hadoop几个模块的程序我们大致有了点了解,现在我们得细看一下这个程序是如何处理命令的. 我们就从原头开始,然后一步步追查. 我们先选中ls命 ...

  5. 三、hdfs的JavaAPI操作

    下文展示Java的API如何操作hdfs,在这之前你需要先安装配置好hdfs https://www.cnblogs.com/lay2017/p/9919905.html 依赖 你需要引入依赖如下 & ...

  6. vim 配置文件.vimrc,高亮+自动缩进+行号+折叠+优化

    将一下代码copy到 用户目录下 新建文件为  .vimrc保存即可生效: 如果想所有用户生效 请修改 /etc/vimrc (建议先cp一份)"====================== ...

  7. python中参数传递的方法

    Python中函数传递参数的形式主要有以下五种,分别为位置传递,关键字传递,默认值传递,不定参数传递(包裹传递)和解包裹传递. 1.位置传递实例: def fun(a,b,c) return a+b+ ...

  8. 关于META你知道多少

    META标签,是HTML语言head区的一个辅助性标签.在几乎所有的page里,我们都可以看 到类似下面这段html代码: -------------------------------------- ...

  9. Android热修复之AndFix使用教程

    AndFix的github地址 AndFix 全称Android hot-fix,是alibaba的Android热修复框架,支持Android 2.3到6.0的版本,支持arm与X86系统架构,支持 ...

  10. 网页简单布局之结构与表现原则(HTML/CSS)

    结构 样式 行为真正的分离 前端初级人员会在页面上单纯的用各个div把相关内容独立开: 前端中级人员明白相关属性的设置会给元素带来什么改变,从而减少div的书写: 前端高级人员会以及其简单的和稳定的方 ...