zoukankan      html  css  js  c++  java
  • 即时通信4

    xmpp整理笔记:聊天信息的发送与显示

     

    任何一个信息的发送都需要关注两个部分,信息的发出,和信息在界面中的显示

    往期回顾:

    xmpp整理笔记:环境的快速配置(附安装包)  http://www.cnblogs.com/zhonghuaxiaodangjia/p/4323460.html

    xmpp整理笔记:xmppFramework框架的导入和介绍  http://www.cnblogs.com/zhonghuaxiaodangjia/p/4323475.html 

    xmpp整理笔记:用户网络连接及好友管理  http://www.cnblogs.com/zhonghuaxiaodangjia/p/4323505.html

    需要注意一点:

    聊天界面输入框并不是textField而是textView,因为textView可以控制多行信息间的上下滚动编辑,如果微信下面的聊天框用的是普通的textField你可以想象会出现什么情况。

    用模拟器程序和小鸭子聊天效果图如下:

    一。信息的发送

    首先要有一个结果调度器

    这是通过coredata从SQLlite取数据的必要操作。所有代码写在这个懒加载中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    - (NSFetchedResultsController *)fetchedResultsController {
        // 推荐写法,减少嵌套的层次
        if (_fetchedResultsController != nil) {
            return _fetchedResultsController;
        }
         
        // 先确定需要用到哪个实体
        NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"XMPPMessageArchiving_Message_CoreDataObject"];
         
        // 排序
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"timestamp" ascending:YES];
        request.sortDescriptors = @[sort];
         
        // 每一个聊天界面,只关心聊天对象的消息
        request.predicate = [NSPredicate predicateWithFormat:@"bareJidStr = %@"self.chatJID.bare];
         
        // 从自己写的工具类里的属性中得到上下文
        NSManagedObjectContext *ctx = [SXXMPPTools sharedXMPPTools].xmppMessageArchivingCoreDataStorage.mainThreadManagedObjectContext;
         
        // 实例化,里面要填上上面的各种参数
        _fetchedResultsController = [[NSFetchedResultsController alloc]
          initWithFetchRequest:request managedObjectContext:ctx sectionNameKeyPath:nil cacheName:nil];
        _fetchedResultsController.delegate = self;
         
        return _fetchedResultsController;
    }

    写完了结果调度器之后要切记在viewdidload页面首次加载中加上一句,否则不干活

    1
    2
    // 查询数据
        [self.fetchedResultsController performFetch:NULL];

    发送出消息 

    因为textView里面没有类似textField的shouldReturn的方法 直接发送信息

    所以只能对textView的《代理方法之文本改变方法》 稍加处理达到文本发送的目的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #pragma mark - ******************** textView代理方法
    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    {
        // 判断按下的是不是回车键。
        if ([text isEqualToString:@" "]) {
             
            // 自定义的信息发送方法,传入字符串直接发出去。
            [self sendMessage:textView.text];
             
            self.textView.text = nil;
             
            return NO;
        }
        return YES;
    }

     在输入时如果按下回车键那触发代理方法传入的这个字符就是" " 就会调用自己写的 这个sendMessage方法,传入一个字符串直接发出去。

    这个方法内部把传入的文本先addBody 再用自己手写的单例类的xmpp流 发出去。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #pragma mark - ******************** 发送消息方法
    /** 发送信息 */
    - (void)sendMessage:(NSString *)message
    {
        XMPPMessage *msg = [XMPPMessage messageWithType:@"chat" to:self.chatJID];
         
        [msg addBody:message];
         
        [[SXXMPPTools sharedXMPPTools].xmppStream sendElement:msg];
    }

    二。信息在tableView中的显示

    是在tableView的数据源方法中,先从数据库中取出当前的信息,再判断是发出去的还是接收的。取到不同的可重用标识符,然后赋值

    1
    2
    3
    4
    5
    6
        // 取出当前行的消息
        XMPPMessageArchiving_Message_CoreDataObject *message = [self.fetchedResultsController objectAtIndexPath:indexPath];
    // 判断是发出消息还是接收消息
        NSString *ID = ([message.outgoing intValue] == 1) ? @"SendCell" : @"ReciveCell" ;
        SXChatCell *cell = [tableview dequeueReusableCellWithIdentifier:ID];
        cell.messageLabel.text = message.body;

     其中sx开的的类名都是我自定义的类,里面都是常规写法。

    关于上面提到的工具类SXXmppTools里 这个模块需要用到得属性和方法有

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /** xmpp流 */
    @property(nonatomic,strong,readonly) XMPPStream * xmppStream;
    /** 消息归档 */
    @property (nonatomic, strong, readonly) XMPPMessageArchiving *xmppMessageArchiving;
    /** 消息归档存储 */
    @property (nonatomic, strong, readonly) XMPPMessageArchivingCoreDataStorage *xmppMessageArchivingCoreDataStorage;
     
     
    + (instancetype)sharedXMPPTools;

    这里有一点需要注意,

    因为默认情况下你一进入一位好友的聊天页面,你和所有好友的聊天记录都会显示。因为都是存在同一个数据表里的啊,因此需要做一层过滤,就是懒加载中的这行代码

    1
    2
    // 每一个聊天界面,只关心聊天对象的消息
        request.predicate = [NSPredicate predicateWithFormat:@"bareJidStr = %@"self.chatJID.bare];

     

  • 相关阅读:
    了解web前端基本常识
    解决移动端输入法挡住输入框的办法
    简单实现根据选项显示不同的表单
    关于“使用本服务器,放到正规的第三方服务器就不安全”的想法
    简单实现网页换肤功能
    Java项目引入eclipse注意事项
    hexo博客发布注意事项
    hexo博客出现“Cannot GET/xxxx”的错误
    C#中ToString()格式详解
    SQLSERVER 时间日期函数,查询今天日期、昨天、一个星期、半年前的数据
  • 原文地址:https://www.cnblogs.com/zhonghuaxiaodangjia/p/4323551.html
Copyright © 2011-2022 走看看