zoukankan      html  css  js  c++  java
  • ios xmpp demo

    为了方便程序调用,我们把XMPP的一些主要方法写在AppDelegate中


    在AppDelegate.m下这几个方法为:

     

    1. -(void)setupStream{  
    2.       
    3.     //初始化XMPPStream  
    4.     xmppStream = [[XMPPStream alloc] init];  
    5.     [xmppStream addDelegate:self delegateQueue:dispatch_get_current_queue()];  
    6.       
    7. }  
    8.   
    9. -(void)goOnline{  
    10.       
    11.     //发送在线状态  
    12.     XMPPPresence *presence = [XMPPPresence presence];  
    13.     [[self xmppStream] sendElement:presence];  
    14.       
    15. }  
    16.   
    17. -(void)goOffline{  
    18.       
    19.     //发送下线状态  
    20.     XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];  
    21.     [[self xmppStream] sendElement:presence];  
    22.       
    23. }  
    24.   
    25. -(BOOL)connect{  
    26.       
    27.     [self setupStream];  
    28.       
    29.     //从本地取得用户名,密码和服务器地址  
    30.     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];  
    31.       
    32.     NSString *userId = [defaults stringForKey:USERID];  
    33.     NSString *pass = [defaults stringForKey:PASS];  
    34.     NSString *server = [defaults stringForKey:SERVER];  
    35.       
    36.     if (![xmppStream isDisconnected]) {  
    37.         return YES;  
    38.     }  
    39.       
    40.     if (userId == nil || pass == nil) {  
    41.         return NO;  
    42.     }  
    43.       
    44.     //设置用户  
    45.     [xmppStream setMyJID:[XMPPJID jidWithString:userId]];  
    46.     //设置服务器  
    47.     [xmppStream setHostName:server];  
    48.     //密码  
    49.     password = pass;  
    50.       
    51.     //连接服务器  
    52.     NSError *error = nil;  
    53.     if (![xmppStream connect:&error]) {  
    54.         NSLog(@"cant connect %@", server);  
    55.         return NO;  
    56.     }  
    57.       
    58.     return YES;  
    59.   
    60. }  
    61.   
    62. -(void)disconnect{  
    63.       
    64.     [self goOffline];  
    65.     [xmppStream disconnect];  
    66.       
    67. }  

    这几个是基础方法,接下来就是XMPPStreamDelegate中的方法,也是接受好友状态,接受消息的重要方法

     

     

    1. //连接服务器  
    2. - (void)xmppStreamDidConnect:(XMPPStream *)sender{  
    3.       
    4.     isOpen = YES;  
    5.     NSError *error = nil;  
    6.     //验证密码  
    7.     [[self xmppStream] authenticateWithPassword:password error:&error];  
    8.       
    9. }  
    10.   
    11. //验证通过  
    12. - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender{  
    13.       
    14.     [self goOnline];  
    15. }  
    16.   
    17. //收到消息  
    18. - (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message{  
    19.       
    20. //    NSLog(@"message = %@", message);  
    21.       
    22.     NSString *msg = [[message elementForName:@"body"] stringValue];  
    23.     NSString *from = [[message attributeForName:@"from"] stringValue];  
    24.       
    25.     NSMutableDictionary *dict = [NSMutableDictionary dictionary];  
    26.     [dict setObject:msg forKey:@"msg"];  
    27.     [dict setObject:from forKey:@"sender"];  
    28.       
    29.     //消息委托(这个后面讲)  
    30.     [messageDelegate newMessageReceived:dict];  
    31.       
    32. }  
    33.   
    34. //收到好友状态  
    35. - (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence{  
    36.       
    37. //    NSLog(@"presence = %@", presence);  
    38.       
    39.     //取得好友状态  
    40.     NSString *presenceType = [presence type]; //online/offline  
    41.     //当前用户  
    42.     NSString *userId = [[sender myJID] user];  
    43.     //在线用户  
    44.     NSString *presenceFromUser = [[presence from] user];  
    45.       
    46.     if (![presenceFromUser isEqualToString:userId]) {  
    47.           
    48.         //在线状态  
    49.         if ([presenceType isEqualToString:@"available"]) {  
    50.               
    51.             //用户列表委托(后面讲)  
    52.             [chatDelegate newBuddyOnline:[NSString stringWithFormat:@"%@@%@", presenceFromUser, @"nqc1338a"]];  
    53.               
    54.         }else if ([presenceType isEqualToString:@"unavailable"]) {  
    55.             //用户列表委托(后面讲)  
    56.             [chatDelegate buddyWentOffline:[NSString stringWithFormat:@"%@@%@", presenceFromUser, @"nqc1338a"]];  
    57.         }  
    58.           
    59.     }  
    60.   
    61. }  

    这里面有两个委托方法,一个是用户列表委托,还有一个就是消息委托,用户列表委托主要就是取得在线用户,更新用户TableView,消息委托就是取得好友发送的消息,并更新消息TableView,当然这两个TableView是在不同的Controller中的

     



    定义完两个委托,我们就要在不同的Controller中实现这两个委托了

    在好友Controller中实现<KKChatDelegate>并写入如下方法

     

    1. //取得当前程序的委托  
    2. -(KKAppDelegate *)appDelegate{  
    3.       
    4.     return (KKAppDelegate *)[[UIApplication sharedApplication] delegate];  
    5.       
    6. }  
    7.   
    8. //取得当前的XMPPStream  
    9. -(XMPPStream *)xmppStream{  
    10.       
    11.     return [[self appDelegate] xmppStream];  
    12. }  
    13.   
    14. //在线好友  
    15. -(void)newBuddyOnline:(NSString *)buddyName{  
    16.       
    17.     if (![onlineUsers containsObject:buddyName]) {  
    18.         [onlineUsers addObject:buddyName];  
    19.         [self.tView reloadData];  
    20.     }  
    21.       
    22. }  
    23.   
    24. //好友下线  
    25. -(void)buddyWentOffline:(NSString *)buddyName{  
    26.       
    27.     [onlineUsers removeObject:buddyName];  
    28.     [self.tView reloadData];  
    29.       
    30. }  

    在viewDidLoad中加入

     

     

    1. //设定在线用户委托  
    2.     KKAppDelegate *del = [self appDelegate];  
    3.     del.chatDelegate = self;  

    这两行代码,让好友列表的委托实现方法在本程序中

     

    viewWillAppear中加入

     

    1. [super viewWillAppear:animated];  
    2.   
    3. NSString *login = [[NSUserDefaults standardUserDefaults] objectForKey:@"userId"];  
    4.   
    5. if (login) {  
    6.       
    7.     if ([[self appDelegate] connect]) {  
    8.         NSLog(@"show buddy list");  
    9.           
    10.     }  
    11.       
    12. }else {  
    13.       
    14.     //设定用户  
    15.     [self Account:self];  
    16.       
    17. }  

    判断本地保存的数据中是否有userId,没有的话就跳转到登录页面

     

    这里最重要的就是connect了,这一句话就是登录了,成功的话,页面就会显示好友列表了。

     

    1. #pragma mark UITableViewDelegate  
    2. -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{  
    3.       
    4.     //start a Chat  
    5.     chatUserName = (NSString *)[onlineUsers objectAtIndex:indexPath.row];  
    6.       
    7.     [self performSegueWithIdentifier:@"chat" sender:self];  
    8.       
    9. }  
    10. -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{  
    11.       
    12.     if ([segue.identifier isEqualToString:@"chat"]) {  
    13.         KKChatController *chatController = segue.destinationViewController;  
    14.         chatController.chatWithUser = chatUserName;  
    15.     }  
    16. }  

     

    当显示出好友列表,我们选择一个好友进行聊天

     

    将当前好友名称发送给聊天页面

    下面是聊天Controller了

    在KKChatController.h中加入

     

    1. NSMutableArray *messages;  

    这是我们要显示的消息,每一条消息为一条字典

     

    接下来就是每一条消息的显示了

     

    1. -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{  
    2.       
    3.     static NSString *identifier = @"msgCell";  
    4.       
    5.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];  
    6.       
    7.     if (cell == nil) {  
    8.         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];  
    9.     }  
    10.       
    11.     NSMutableDictionary *dict = [messages objectAtIndex:indexPath.row];  
    12.       
    13.     cell.textLabel.text = [dict objectForKey:@"msg"];  
    14.     cell.detailTextLabel.text = [dict objectForKey:@"sender"];  
    15.     cell.accessoryType = UITableViewCellAccessoryNone;  
    16.       
    17.     return cell;  
    18.       
    19. }  

    跟上面好友Controller一样,这里我们也需要XMPPStream

     

     

    1. -(KKAppDelegate *)appDelegate{  
    2.       
    3.     return (KKAppDelegate *)[[UIApplication sharedApplication] delegate];  
    4. }  
    5.   
    6. -(XMPPStream *)xmppStream{  
    7.       
    8.     return [[self appDelegate] xmppStream];  
    9. }  

    在ViewDidLoad中加入

     

     

    1. KKAppDelegate *del = [self appDelegate];  
    2. del.messageDelegate = self;  

    设定消息委托由自己来接收和处理

     

     

    1. #pragma mark KKMessageDelegate  
    2. -(void)newMessageReceived:(NSDictionary *)messageCotent{  
    3.       
    4.     [messages addObject:messageCotent];  
    5.       
    6.     [self.tView reloadData];  
    7.       
    8. }  

    接下来最重要的就是发送消息了

     

     

    1. - (IBAction)sendButton:(id)sender {  
    2.       
    3.     //本地输入框中的信息  
    4.     NSString *message = self.messageTextField.text;  
    5.       
    6.     if (message.length > 0) {  
    7.           
    8.         //XMPPFramework主要是通过KissXML来生成XML文件  
    9.         //生成<body>文档  
    10.         NSXMLElement *body = [NSXMLElement elementWithName:@"body"];  
    11.         [body setStringValue:message];  
    12.           
    13.         //生成XML消息文档  
    14.         NSXMLElement *mes = [NSXMLElement elementWithName:@"message"];  
    15.         //消息类型  
    16.         [mes addAttributeWithName:@"type" stringValue:@"chat"];  
    17.         //发送给谁  
    18.         [mes addAttributeWithName:@"to" stringValue:chatWithUser];  
    19.         //由谁发送  
    20.         [mes addAttributeWithName:@"from" stringValue:[[NSUserDefaults standardUserDefaults] stringForKey:USERID]];  
    21.         //组合  
    22.         [mes addChild:body];  
    23.           
    24.         //发送消息  
    25.         [[self xmppStream] sendElement:mes];  
    26.           
    27.         self.messageTextField.text = @"";  
    28.         [self.messageTextField resignFirstResponder];  
    29.           
    30.         NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];  
    31.           
    32.         [dictionary setObject:message forKey:@"msg"];  
    33.         [dictionary setObject:@"you" forKey:@"sender"];  
    34.   
    35.         [messages addObject:dictionary];  
    36.           
    37.         //重新刷新tableView  
    38.         [self.tView reloadData];  
    39.           
    40.     }  
    41.       
    42.       
    43. }  
  • 相关阅读:
    接口文档神器之apidoc
    ApiDoc 后端接口注释文档的使用
    Golang 数组和切片
    go切片展开
    Go的json解析:Marshal与Unmarshal
    golang depth read map
    golang 多级json转map
    GoLang中 json、map、struct 之间的相互转化
    利用delve(dlv)在Visual Code中进行go程序的远程调试-debug方式
    maximum-depth-of-binary-tree——找出数的最大深度
  • 原文地址:https://www.cnblogs.com/yulang314/p/3549595.html
Copyright © 2011-2022 走看看