#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, 0)]; } #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 = 5222; // 链接
NSError *err = nil; if(![_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&err]){ NSLog(@"%@",err); } } #pragma mark 链接到服务成功后,再发送密码受权
-(void)sendPwdToHost{ NSLog(@"再发送密码受权"); NSError *err = nil; [_xmppStream authenticateWithPassword:@"123456" 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工具(登陆,注册,注销) android
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, 0)]; } #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 = 5222; // 链接 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
自动登陆app
AppDelegate.m dom
#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
登陆方法iphone
#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; }