首先先来段废话介绍一下XMPP
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. self.window=[[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds]; self.window.backgroundColor=[UIColor whiteColor]; [self.window makeKeyAndVisible];//main window出现在最前端 self.window.rootViewController=[[ViewController alloc]init]; return YES; }
// liaoliao // Created by LiuJiawei on 15/11/7. // Copyright © 2015年 LIUjiawei. All rights reserved. // #import <UIKit/UIKit.h> @interface ViewController : UITabBarController @endViewController.m
// liaoliao // // Created by LiuJiawei on 15/11/7. // Copyright © 2015年 LIUjiawei. All rights reserved. // #import "ViewController.h" #import "PersonController.h" #import "RosterController.h" #import "CharRoomController.h" #import "LoginViewController.h" #import "AbilityManage.h" @interface ViewController () @end @implementation ViewController -(id)init{ self=[super init]; if (self){ NSLog(@"init"); } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self createViewControllers];//创造了三个viewcontroller } -(void)createViewControllers{ PersonController *personVC=[[PersonController alloc]init]; //个人 RosterController *rosterVC=[[RosterController alloc]init]; //好友列表 ChatRoomController *chatroomVC=[[ChatRoomController alloc]init];//群组 NSArray *array=@[rosterVC,chatroomVC,personVC]; NSArray *titlearray=@[@"好友",@"群组",@"个人中心"]; NSArray *imagearray=@[@"roster",@"chatroom",@"person"]; NSMutableArray *Muarray=[[NSMutableArray alloc] initWithCapacity:3]; for (int i=0; i<3; i++) { UINavigationController *nav=[[UINavigationController alloc]initWithRootViewController:array[i]]; nav.tabBarItem.title=titlearray[i]; nav.tabBarItem.image=[UIImage imageNamed:imagearray[i]]; [Muarray addObject:nav]; } self.viewControllers=Muarray; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onlineNotification:) name:@"Ability_online_Noti" object:nil];
#pragma mark - Notification -(void)onlineNotification:(NSNotification*)notification{ BOOL signin=[notification.object boolValue]; if (signin){ NSLog(@"Roster_queryRosterList"); [[AbilityRoster sharedRoster] queryRosterList];//已经在线了说明登录成功了,所以查找这个帐号拥有的好友 } else{ NSLog(@"LoginViewController"); LoginViewController* loginVC=[[LoginViewController alloc]init];//没有在线,需要登录 [self presentViewController:loginVC animated:YES completion:^{ }]; } }
在登录界面也有一个注册通知
LoginViewController
<span style="font-size:14px;"> [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onlineNotification:) name:@"Ability_online_Noti" object:nil];</span>
-(void)onlineNotification:(NSNotification*)notification{ BOOL online=[notification.object boolValue]; NSLog(@"onlineNotification"); if (online){<span style="white-space:pre"> </span>//在线了登录成功了,登录界面可以消失了 NSLog(@"no-LoginViewController"); [self dismissViewControllerAnimated:YES completion:^{}]; } }
-(void)setOnline:(BOOL)online{ _online=online; if (online){ //发送在线状态 [[NSNotificationCenter defaultCenter] postNotificationName:Ability_online_Noti object:[NSNumber numberWithBool:YES]]; } else{ [[NSNotificationCenter defaultCenter] postNotificationName:Ability_online_Noti object:[NSNumber numberWithBool:NO]]; } }
-(void)viewWillAppear:(BOOL)animated{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onlineNotification:) name:@"Ability_online_Noti" object:nil]; }
-(void)viewDidAppear:(BOOL)animated{ [AbilityManage sharedManager]; }
static AbilityManage *_shareManager=nil; +(AbilityManage *)sharedManager{ if (!_shareManager) { _shareManager=[[self alloc] init]; [_shareManager setupXMPP]; } return _shareManager; } -(void)setupXMPP{ _xmppStream = [[XMPPStream alloc] init]; [_xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];使AbilityManage有XmppStream的协议 [_xmppStream addDelegate:[AbilityRoster sharedRoster] delegateQueue:dispatch_get_main_queue()];使AbilityRoster有XmppStream的协议 #if !TARGET_IPHONE_SIMULATOR { _xmppStream.enableBackgroundingOnSocket = YES; } #endif _xmppReconnect = [[XMPPReconnect alloc] init]; [_xmppReconnect activate:_xmppStream]; self.online=NO;//一般默认是不在线的,同时触发方法-(void)setOnline:(BOOL)online; }
触发方法-(void)setOnline:(BOOL)online;发送的object是NO
-(void)setOnline:(BOOL)online{ _online=online; if (online){ //发送在线状态 [[NSNotificationCenter defaultCenter] postNotificationName:Ability_online_Noti object:[NSNumber numberWithBool:YES]]; } else{ [[NSNotificationCenter defaultCenter] postNotificationName:Ability_online_Noti object:[NSNumber numberWithBool:NO]]; } }
-(void)onlineNotification:(NSNotification*)notification{ BOOL signin=[notification.object boolValue]; if (signin){ NSLog(@"Roster_queryRosterList"); [[AbilityRoster sharedRoster] queryRosterList]; } else{ NSLog(@"LoginViewController"); LoginViewController* loginVC=[[LoginViewController alloc]init]; [self presentViewController:loginVC animated:YES completion:^{ }]; } }
<span style="font-size:14px;">-(IBAction)onButtonDone:(id)sender{ NSString* username=self.username.text; NSString* password=self.password.text; NSString* host=self.hosttext.text; [[NSUserDefaults standardUserDefaults] setObject:username forKey:Username_Key]; [[NSUserDefaults standardUserDefaults] setObject:password forKey:Password_Key]; [[NSUserDefaults standardUserDefaults] setObject:host forKey:Host_Key]; [[NSUserDefaults standardUserDefaults] synchronize]; NSLog(@"onbuttondone"); [[AbilityManage sharedManager] signinWithUsername:username password:password host:host isregister:NO];</span>
<span style="font-size:14px;">//需要AbilltyManage类的登陆功能!!!! }</span>
-(void)signinWithUsername:(NSString *)username password:(NSString *)password host:(NSString *)host isregister:(BOOL)isregister { self.username=username; self.password=password; self.host=host; if (![_xmppStream isDisconnected]){ return; } _registerAction=isregister; self.jid=[NSString stringWithFormat:@"%@@%@",self.username,self.host]; [_xmppStream setMyJID:[XMPPJID jidWithString:_jid resource:@"drrr"]]; [_xmppStream setHostName:host]; NSError *error = nil; BOOL result=[_xmppStream connectWithTimeout:3.0f error:&error]; NSLog(@"connect:%d,%@",result,error); }
2016-01-13 13:15:42:737 Chat[23076:2707] SEND: <?xml version='1.0'?>
2016-01-13 13:15:42:742 Chat[23076:2707] SEND: <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='xxxxx.6655.la'>
2016-01-13 13:15:42:791 Chat[23076:5407] RECV: <stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="xxxxx.6655.la" id="8a7e501" stream1:lang="en" version="1.0"/>
#pragma mark - xmpp delegate -(void)xmppStreamDidConnect:(XMPPStream *)sender{ //验证密码 NSError* error=nil; BOOL result; if (!_registerAction){ result=[_xmppStream authenticateWithPassword:self.password error:&error]; } else{ result=[_xmppStream registerWithPassword:self.password error:&error]; } ///注册只要一次,之后就改为登录,防止在重复连接的时候又去注册 _registerAction=NO; NSLog(@"authenticated:%d,%@",result,error); }因为不是注册,而是登陆,所以执行这条语句 result=[_xmppStream authenticateWithPassword:self.password error:&error];
用xmppStream 的authenticateWithPassword方法进行密码验证,成功的话会响应delegate的方法,就是下面这个
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
//这里我保持着会用就行的立场 -(void)xmppStreamDidAuthenticate:(XMPPStream *)sender{ //发送在线状态 XMPPPresence *presence = [XMPPPresence presence]; [_xmppStream sendElement:presence]; }发送了presence,也会受到一个presence
-(void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence{ XMPPJID* jidFrom=[presence from]; XMPPJID* jidTo=[presence to]; NSString *presenceFromUser = [jidFrom user]; NSString* presenceFromJid=[jidFrom bare]; //取得好友状态 NSString *presenceType = [presence type]; //online/offline //当前用户是否在线 NSString *userId = [[sender myJID] user]; if ([presenceFromUser isEqualToString:userId]){ if ([presenceType isEqualToString:@"available"]){ self.online=YES; //重要在这里 } else if ([presenceType isEqualToString:@"unavailable"]){ self.online=NO; <span style="font-family: 'Helvetica Neue', Helvetica, STheiti, 微软雅黑, 黑体, Arial, Tahoma, sans-serif, serif;">//重要在这里</span> } } }
-(void)setOnline:(BOOL)online{ _online=online; if (online){ //发送在线状态 [[NSNotificationCenter defaultCenter] postNotificationName:Ability_online_Noti object:[NSNumber numberWithBool:YES]]; } else{ [[NSNotificationCenter defaultCenter] postNotificationName:Ability_online_Noti object:[NSNumber numberWithBool:NO]]; } }这个时候由于LoginViewController也实例化了,而他也有通知事件,所以两个对象都会被通知先看RosterViewController
<span style="font-size:14px;">#pragma mark - Notification -(void)onlineNotification:(NSNotification*)notification{ BOOL signin=[notification.object boolValue]; if (signin){ [[AbilityRoster sharedRoster] queryRosterList];//寻找此账号的好友 } else{ NSLog(@"LoginViewController"); LoginViewController* loginVC=[[LoginViewController alloc]init]; [self presentViewController:loginVC animated:YES completion:^{ }]; } }</span>由于是YES了,所以执行寻找好友的方法,对于LoginViewController的通知事件呢
-(void)onlineNotification:(NSNotification*)notification{ BOOL online=[notification.object boolValue]; NSLog(@"onlineNotification"); if (online){ NSLog(@"no-LoginViewController"); [self dismissViewControllerAnimated:YES completion:^{}]; } }很识趣的知道自己该miss了,接着就跳到这个画面了:
至于如何添加好友,并将好友信息找到并显示出来,都是另一个AbilityRoster类负责,下一篇再讲