基于XMPP协议的即时通信

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

登录、注册、添加好友、好友列表、聊天.

1.下载XMPPFramework、并将下列文件拖入工程中。

2.添加所需框架

3.添加Header Search Paths和Other Linker Flags

1libxmlincludes require that the target Header Search Paths contain2///usr/include/libxml23//and Other Linker Flags contain4//-lxml2

4.祛除警告

CGBitmapContextCreate 在 ios7下变化

详情请访问博客

1#if__ipHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_6_12intbitmapInfo = kCGBitmapByteOrderDefault |kCGImageAlphaPRemultipliedLast;3#elseint bitmapInfo = kCGImageAlphaPremultipliedLast; #endif

5.在spark注册账号,注册信息在openfire的ofUser里。

6.开始

1//2//AppDelegate.h3//MyXmpp4//5//Created by ChenJungang on 14-1-3.6//Copyright (c) 2014年 chenjungang. All rights reserved.7//89#import<UIKit/UIKit.h>10#import"XmppManager.h"11@classXmppManager;12@interfaceAppDelegate : UIResponder <UIapplicationDelegate>13{1415}16@property (strong, nonatomic) UIWindow *window;17@property (nonatomic,retain) XmppManager *xmppManager;1819+ (AppDelegate*)shareAppDelegate;2021@end

AppDelegate.h

1//2//AppDelegate.m3//MyXmpp4//5//Created by ChenJungang on 14-1-3.6//Copyright (c) 2014年 chenjungang. All rights reserved.7//89#import"AppDelegate.h"10#import"RootViewController.h"11#import"LoginViewController.h"12#import"Define.h"13@implementationAppDelegate141516- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions17{1819//初始化xmpp管理类。20_xmppManager =[[XmppManager alloc] init];2122RootViewController * rootViewController =[[RootViewController alloc] init];23UINavigationController * navigationController =[[UINavigationController alloc] initWithRootViewController:rootViewController];24self.window =[[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];25self.window.backgroundColor =[UIColor whiteColor];26self.window.rootViewController =navigationController;27[rootViewController release];28[navigationController release];29[self.window makeKeyAndVisible];303132//如果未登录,拉起登录页面33NSUserDefaults * userDefaults =[NSUserDefaults standardUserDefaults];34NSDictionary * userInfo =[userDefaults objectForKey:USER_INFO_KEY];35if(!userInfo)36{37LoginViewController * loginVC =[[LoginViewController alloc] init];38UINavigationController * loginNav =[[UINavigationController alloc] initWithRootViewController:loginVC];39[loginVC release];40[navigationController presentViewController:loginNav animated:YES completion:^{41}];42}434445returnYES;46}4748+ (AppDelegate*)shareAppDelegate49{50return(AppDelegate*)[UIApplication sharedApplication].delegate;51}5253- (void)applicationWillResignActive:(UIApplication *)application54{5556}5758- (void)applicationDidEnterBackground:(UIApplication *)application59{60[_xmppManager disconnect];61}6263- (void)applicationWillEnterForeground:(UIApplication *)application64{6566}6768- (void)applicationDidBecomeActive:(UIApplication *)application69{70[_xmppManager connect];7172}7374- (void)applicationWillTerminate:(UIApplication *)application75{76[_xmppManager disconnect];77}7879- (void)dealloc80{81[_xmppManager release];82[_window release];83[super dealloc];84}8586@end

AppDelegate.m

1//2//XmppManager.h3//MyXmpp4//5//Created by ChenJungang on 14-1-3.6//Copyright (c) 2014年 chenjungang. All rights reserved.7//89#import<Foundation/Foundation.h>1011@classXMPPStream;12@interfaceXmppManager : NSObject13{14XMPPStream *xmppStream;15NSString * passWord;//密码16}17@property(nonatomic,readonly)XMPPStream *xmppStream;18@property(nonatomic,assign)idchatDelegate;19@property(nonatomic,assign)idstatusDelegate;202122//连接23-(BOOL)connect;24//断开25- (void)disconnect;26//设置XMPPStream27- (void)setupStream;28//上线29- (void)goOnline;30//下线31- (void)goOffline;32@end333435@protocolChatMessageDelegate <NSObject>3637- (void)chatMessageDidReceived:(NSDictionary *)messageDic;3839@end4041@protocolFriendStautsDelegate <NSObject>4243- (void)friendStatusDidOnLine:(NSDictionary *)statusDic;44- (void)friendStatusDidOffLine:(NSDictionary *)statusDic;4546@end

XmppManager.h

1//2//XmppManager.m3//MyXmpp4//5//Created by ChenJungang on 14-1-3.6//Copyright (c) 2014年 chenjungang. All rights reserved.7//89#import"XmppManager.h"10#import"Define.h"11#import"XMPP.h"1213@implementationXmppManager1415//初始化XMPPStream16-(void)setupStream17{18xmppStream =[[XMPPStream alloc] init];19[xmppStream addDelegate:self delegateQueue:dispatch_get_current_queue()];2021}2223//发送在线状态24-(void)goOnline{2526XMPPPresence *presence =[XMPPPresence presence];27[[self xmppStream] sendElement:presence];2829}3031//发送下线状态32-(void)goOffline{3334XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];35[[self xmppStream] sendElement:presence];3637}3839//连接40-(BOOL)connect{4142[self setupStream];4344//从本地取得用户名,密码和服务器地址45NSUserDefaults * defaults =[NSUserDefaults standardUserDefaults];46NSDictionary * userInfoDic =[defaults objectForKey:USER_INFO_KEY];47NSString * userId =[userInfoDic objectForKey:NAME_KEY];48NSString * pass =[userInfoDic objectForKey:PASSWORD_KEY];49NSString * server =[userInfoDic objectForKey:SERVER_KEY];5051//通常xmpp服务器的ip地址是公网Ip,通信的用户名就是 用户名@服务器地址 类似邮箱地址52//NSString * trueUserId = [NSString stringWithFormat:@"%@@%@",userId,server];5354//因蓝鸥的xmpp服务器地址 是搭建在内网ip上,所以用户名的server 需要用“localhost”才能正常通信,不能使用内网ip作为sever地址55NSString * trueUserId = [NSString stringWithFormat:@"%@@%@",userId,@"localhost"];5657if(![xmppStream isDisconnected])58{59returnYES;60}6162if(trueUserId == nil || pass ==nil)63{64returnNO;65}6667//设置用户68[xmppStream setMyJID:[XMPPJID jidWithString:trueUserId]];69//设置服务器70[xmppStream setHostName:server];71//密码72password =pass;7374//连接服务器75NSError *error =nil;76if(![xmppStream connect:&error])77{78NSLog(@"cant connect %@", server);79returnNO;80}else81{82NSLog(@"connect %@ successful", server);83}8485returnYES;8687}8889//断开连接90- (void)disconnect91{9293[self goOffline];94[xmppStream disconnect];9596}9798//此方法在stream开始连接服务器的时候调用99- (void)xmppStreamDidConnect:(XMPPStream *)sender{100101NSError *error =nil;102//验证密码103[[self xmppStream] authenticateWithPassword:password error:&error];104}105106//验证成功后调用107- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender{108109//发送上线状态110[self goOnline];111}112113//验证失败后调用114- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error115{116NSLog(@"auth failer");117}118119//收到消息120- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message{121122NSLog(@"xml message = %@", message);123124NSString * msg = [[message elementForName:@"body"] stringValue];125NSString * fromUser = [[message attributeForName:@"from"] stringValue];126NSString * toUser = [[message attributeForName:@"to"] stringValue];127//这个开源项目一个bug,有时键盘刚一输入时会收到空消息128if(!msg) {129NSLog(@"msg == nil!");130return;131}132133//封装一个消息字典,回传给使用类134NSMutableDictionary *dict =[NSMutableDictionary dictionary];135[dict setObject:msg forKey:@"message"];136[dict setObject:fromUser forKey:@"fromUserId"];137[dict setObject:toUser forKey:@"toUserId"];138139NSLog(@"receive message = %@",msg);140NSLog(@"chat delegate = %@",_chatDelegate);141if(_chatDelegate &&[_chatDelegate respondsToSelector:@selector(chatMessageDidReceived:)])142{143[_chatDelegate chatMessageDidReceived:dict];144}145146}147148//接受到好友状态更新149- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence150{151152NSLog(@"presence = %@", presence);153154//取得好友状态155NSString *presenceType = [presence type];//online/offline156//当前用户157NSString *userId =[[sender myJID] user];158//在线用户159NSString *presenceFromUser =[[presence from] user];160161162NSLog(@"tyep = %@",presenceType);163if(![presenceFromUser isEqualToString:userId]) {164165NSMutableDictionary * statusDic = [NSMutableDictionary dictionaryWithCapacity:1];166167//在线状态,用来把好友划分在在线列表还是离线列表168if([presenceType isEqualToString:@"available"])169{170[statusDic setObject:presenceFromUser forKey:@"name"];171[statusDic setObject:@"available"forKey:@"status"];172173174NSLog(@"status delegate = %@",_statusDelegate);175//通知delegate 上线176if(_statusDelegate &&[_statusDelegate respondsToSelector:@selector(friendStatusDidOnLine:)])177{178//NSLog(@"aaa");179[_statusDelegate friendStatusDidOnLine:statusDic];180}181182183}elseif([presenceType isEqualToString:@"unavailable"])184{185186[statusDic setObject:presenceFromUser forKey:@"name"];187[statusDic setObject:@"unavailable"forKey:@"status"];188189//通知delegate 下线190if(_statusDelegate &&[_statusDelegate respondsToSelector:@selector(friendStatusDidOnLine:)])191{192[_statusDelegate friendStatusDidOffLine:statusDic];193}194195}196197}198}199200//重写getter方法201- (XMPPStream *)xmppStream202{203if(!xmppStream)204{205xmppStream =[[XMPPStream alloc] init];206[xmppStream addDelegate:self delegateQueue:dispatch_get_current_queue()];207}208returnxmppStream;209}210211212@end

XmppManager.m

1//2//LoginViewController.h3//MyXmpp4//5//Created by ChenJungang on 14-1-3.6//Copyright (c) 2014年 chenjungang. All rights reserved.7//89#import<UIKit/UIKit.h>1011@interfaceLoginViewController : UIViewController12{13UITextField *_userName;14UITextField *_passWorld;15UITextField *_server;1617}18@end

LoginViewController.h

1//2//LoginViewController.m3//MyXmpp4//5//Created by ChenJungang on 14-1-3.6//Copyright (c) 2014年 chenjungang. All rights reserved.7//89#import"LoginViewController.h"10#import"Define.h"1112@interfaceLoginViewController ()1314@end1516@implementationLoginViewController171819- (void)viewDidLoad20{21[super viewDidLoad];2223CGFloat x =80;24CGFloat y =20;25CGFloat w =160;26CGFloat h =30;27CGRect rect =CGRectMake(x, y, w, h);28_userName =[[UITextField alloc] init];29_userName.frame =rect;30_userName.borderStyle =UITextBorderStyleRoundedRect;31_userName.placeholder =@"user name";32_userName.text =@"";33[self.view addSubview:_userName];3435x =x;36y = y + h +30;37w =w;38h =h;39rect =CGRectMake(x, y, w, h);40_passWorld =[[UITextField alloc] init];41_passWorld.frame =rect;42_passWorld.borderStyle =UITextBorderStyleRoundedRect;43_passWorld.placeholder =@"password";44_passWorld.text =@"";45[self.view addSubview:_passWorld];4647x =x;48y = y + h +30;49w =w;50h =h;51rect =CGRectMake(x, y, w, h);52_server =[[UITextField alloc] init];53_server.frame =rect;54_server.borderStyle =UITextBorderStyleRoundedRect;55_server.placeholder =@"server";56_server.text =@"";57[self.view addSubview:_server];585960UIBarButtonItem * barButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"login"61style:UIBarButtonItemStyleBordered62target:self63action:@selector(login)];64self.navigationItem.rightBarButtonItem =barButtonItem;65[barButtonItem release];6667}6869- (void)login70{71if([_userName.text isEqualToString:@""] ||72[_passWorld.text isEqualToString:@""] ||73[_passWorld.text isEqualToString:@""])74{75UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示"76message:@"信息不完整!"77delegate:self78cancelButtonTitle:@"确定"79otherButtonTitles:nil, nil];80[alertView show];81[alertView release];8283return;84}8586NSDictionary * dic =[NSDictionary dictionaryWithObjectsAndKeys:87_userName.text,NAME_KEY,88_passWorld.text,PASSWORD_KEY,89_server.text,SERVER_KEY, nil];9091//登录信息存入本地92NSUserDefaults * userDefault =[NSUserDefaults standardUserDefaults];93[userDefault setObject:dic forKey:USER_INFO_KEY];9495[self dismissViewControllerAnimated:YES completion:^{9697}];98}99100101- (void)dealloc102{103[_userName release];104[_passWorld release];105[_server release];106[super dealloc];107}108109110111@end

LoginViewController.m

1//2//RootViewController.h3//MyXmpp4//5//Created by ChenJungang on 14-1-3.6//Copyright (c) 2014年 chenjungang. All rights reserved.7//89#import<UIKit/UIKit.h>1011@interfaceRootViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>12{1314}15@property (nonatomic,retain)UITableView *tableView;16@property (nonatomic,retain)NSMutableArray *dataArray;17@end

RootViewController.h

1//2//RootViewController.m3//MyXmpp4//5//Created by ChenJungang on 14-1-3.6//Copyright (c) 2014年 chenjungang. All rights reserved.7//89#import"RootViewController.h"10#import"ChatViewController.h"1112#import"AppDelegate.h"13#import"Define.h"1415@interfaceRootViewController ()1617@end1819@implementationRootViewController2021- (void)viewDidLoad22{23[super viewDidLoad];2425self.navigationItem.title =@"好友列表";2627//好友listview28_tableView =[[UITableView alloc] initWithFrame:29CGRectMake(0,0,320, self.view.bounds.size.height)30style:UITableViewStylePlain];31_tableView.delegate=self;32_tableView.dataSource =self;33[self.view addSubview:_tableView];3435self.dataArray =[NSMutableArray array];363738//设置好友状态的delegate39[AppDelegate shareAppDelegate].xmppManager.statusDelegate =self;40}4142- (void)viewWillAppear:(BOOL)animated43{44[super viewWillAppear:animated];4546//如果已经登录过,让xmpp 连接47NSUserDefaults * defaults =[NSUserDefaults standardUserDefaults];48NSDictionary * userInfo =[defaults objectForKey:USER_INFO_KEY];49if(userInfo)50{51[[AppDelegate shareAppDelegate].xmppManager connect];52}5354}5556- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section57{58return_dataArray.count;59}6061- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath62{6364staticNSString * cellIndentifier =@"cell";65UITableViewCell * cell =[tableView dequeueReusableCellWithIdentifier:cellIndentifier];66if(!cell)67{68cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentifier] autorelease];69}7071NSString * userName =[self.dataArray objectAtIndex:indexPath.row];7273cell.textLabel.text =userName;74returncell;75}7677//选择和某人聊天78- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath79{80NSString * name =[self.dataArray objectAtIndex:indexPath.row];81ChatViewController * chatViewController =[[ChatViewController alloc] initWithUserName:name];82[self.navigationController pushViewController:chatViewController animated:YES];83[chatViewController release];84}8586#pragmaFriend status delegate87//收到好友上线状态88- (void)friendStatusDidOnLine:(NSDictionary *)statusDic89{90NSString * name = [statusDic objectForKey:@"name"];91if(![_dataArray containsObject:name]) {92[_dataArray addObject:name];93[_tableView reloadData];94}95}9697//收到好友下线状态98- (void)friendStatusDidOffLine:(NSDictionary *)statusDic99{100NSString * name = [statusDic objectForKey:@"name"];101[_dataArray removeObject:name];102[_tableView reloadData];103}104105106107- (void)dealloc108{109[_tableView release];110[super dealloc];111}112@end

RootViewController.m

1//2//ChatViewController.h3//MyXmpp4//5//Created by ChenJungang on 14-1-3.6//Copyright (c) 2014年 chenjungang. All rights reserved.7//89#import<UIKit/UIKit.h>1011@interfaceChatViewController : UIViewController<UIScrollViewDelegate>12{1314}1516@property (nonatomic,copy)NSString *chatUserName;17@property (nonatomic,retain)UITextField *chatInputTextField;18@property (nonatomic,retain)UILabel *chatReceiveLabel;19@property (nonatomic,retain)UILabel *chatSendLabel;2021- (id)initWithUserName:(NSString *)userName;222324@end

ChatViewController.h

1//2//ChatViewController.m3//MyXmpp4//5//Created by ChenJungang on 14-1-3.6//Copyright (c) 2014年 chenjungang. All rights reserved.7//89#import"ChatViewController.h"10#import"XMPP.h"11#import"Define.h"12#import"AppDelegate.h"1314@interfaceChatViewController ()1516@end1718@implementationChatViewController1920//重新初始化方法,确定和谁聊天21- (id)initWithUserName:(NSString *)userName22{23self =[super init];24if(self)25{26self.chatUserName =userName;2728//设置收到消息后的delegate29[AppDelegate shareAppDelegate].xmppManager.chatDelegate =self;30}31returnself;32}333435- (void)viewDidLoad36{3738[super viewDidLoad];3940self.navigationItem.title = [NSString stringWithFormat:@"与%@聊天中",_chatUserName];4142//输入框。43self.chatInputTextField = [[UITextField alloc] initWithFrame:CGRectMake(20,20,200,30)];44_chatInputTextField.borderStyle =UITextBorderStyleRoundedRect;45[self.view addSubview:_chatInputTextField];46[_chatInputTextField release];4748//发送button49UIButton * sendButton =[UIButton buttonWithType:UIButtonTypeRoundedRect];50[sendButton setFrame:CGRectMake(_chatInputTextField.frame.origin.x51+ _chatInputTextField.frame.size.width +10,52_chatInputTextField.frame.origin.y,60,30)];53[sendButton setTitle:@"发送"forState:UIControlStateNormal];54[sendButton addTarget:self action:@selector(sendMessage:) forControlEvents:UIControlEventTouchUpInside];55[self.view addSubview:sendButton];5657//显示收到的文本label58self.chatReceiveLabel =[[UILabel alloc] initWithFrame:59CGRectMake(_chatInputTextField.frame.origin.x,60_chatInputTextField.frame.origin.y +61_chatInputTextField.frame.size.height +20,270,100)];62_chatReceiveLabel.numberOfLines =0;63_chatReceiveLabel.lineBreakMode =NSLineBreakByWordWrapping;64_chatReceiveLabel.backgroundColor =[UIColor grayColor];65[self.view addSubview:_chatReceiveLabel];66[_chatReceiveLabel release];676869//显示发送的文本label70self.chatSendLabel = [[UILabel alloc] initWithFrame:CGRectMake(_chatReceiveLabel.frame.origin.x, _chatReceiveLabel.frame.origin.y + _chatReceiveLabel.frame.size.height+10,270,100)];71_chatSendLabel.numberOfLines =0;72_chatSendLabel.lineBreakMode =NSLineBreakByWordWrapping;73_chatSendLabel.backgroundColor =[UIColor grayColor];74[self.view addSubview:_chatSendLabel];75[_chatSendLabel release];767778}7980//组装发消息的xml内容81- (void)sendMessage:(id)sender82{83//本地输入框中的信息84NSString *message =self.chatInputTextField.text;8586if(message.length >0) {878889//XMPPFramework主要是通过KissXML来生成XML文件90//生成<body>文档91NSXMLElement *body = [NSXMLElement elementWithName:@"body"];92[body setStringValue:message];9394//生成XML消息文档95NSXMLElement *mes = [NSXMLElement elementWithName:@"message"];96//消息类型97[mes addAttributeWithName:@"type"stringValue:@"chat"];98//发送给谁99NSString * toUser = [NSString stringWithFormat:@"%@@%@",_chatUserName,@"localhost"];100101[mes addAttributeWithName:@"to"stringValue:toUser];102//由谁发送103NSDictionary * userInfo =[[NSUserDefaults standardUserDefaults] objectForKey:USER_INFO_KEY];104NSString * formUser = [NSString stringWithFormat:@"%@@%@",[userInfo objectForKey:NAME_KEY],@"localhost"];105[mes addAttributeWithName:@"from"stringValue:formUser];106//组合107[mes addChild:body];108109//发送消息110[[self xmppStream] sendElement:mes];111112113self.chatInputTextField.text =@"";114self.chatSendLabel.text = [NSString stringWithFormat:@"发送了:%@",message];115[self.chatInputTextField resignFirstResponder];116117}118119}120121122- (void)viewWillDisappear:(BOOL)animated123{124125[super viewWillDisappear:animated];126127//delegate 赋空128[AppDelegate shareAppDelegate].xmppManager.chatDelegate =nil;129130}131132//收到消息后的代理回调。133- (void)chatMessageDidReceived:(NSDictionary *)messageDic134{135NSString * message = [messageDic objectForKey:@"message"];136self.chatReceiveLabel.text = [NSString stringWithFormat:@"收到了:%@",message];137}138139//获取xmppstream140- (XMPPStream *)xmppStream141{142return[[AppDelegate shareAppDelegate].xmppManager xmppStream];143}144145- (void)dealloc146{147self.chatUserName =nil;148[super dealloc];149}150151@end

ChatViewController.m

1//2//Define.h3//MyXmpp4//5//Created by ChenJungang on 14-1-3.6//Copyright (c) 2014年 chenjungang. All rights reserved.7//8910#defineUSER_INFO_KEY @"userInfo"111213#defineNAME_KEY @"account"14#definePASSWORD_KEY @"password"15#defineSERVER_KEY @"server"

Define.h

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航