美文网首页iOS开发-socket
(十二)即时通讯之XMPPFramework花名册

(十二)即时通讯之XMPPFramework花名册

作者: 音符上的码字员 | 来源:发表于2016-08-22 14:17 被阅读242次

    前言

    这也是本人第一次琢磨关于即时通讯方面的内容,结合网上查看的相关资料搭建出来的仿微信小demo,如有意见请多多指教

    具体项目可以在githubWeiChat下载进行查看,如若各位看官老爷觉得还可以请点star

    续前篇(十)即时通讯之XMPPFramework登陆注册

    续前篇(十一)即时通讯之XMPPFramework电子名片

    服务器地址
    **Attention,这里需要改成自己的服务器地址和端口号
    并且数据库和服务器一定要开启哟,不然没法登陆的哟**
    #ifdef DEBUG
    #define kHostName @"192.168.199.111"
    //#define kHostName @"127.0.0.1"
    #define kHostPort 5222
    #else
    #define kHostNanme @""
    #define kHostPort 5222
    #endif
    

    本篇讲的是XMPPFramework的花名册部分

    1.什么是花名册

    花名册就是XMPPRoster类,XMPPRoster可以处理和好友的相关事情,比如或获取好友列表,添加好友,接收好友请求,同意好友添加,拒绝好友添加等.

    2.XMPPRoster相关类

    • XMPPRoster(花名册)
    • XMPPRosterCoreDataStorage(花名册存储类)
    • XMPPRosterStorage(花名册存储代理)
    • XMPPRosterDelegate(花名册操作类)

    3.XMPPRoster的使用

    其实这些模块的使用与之前的模块大同小异,请接着看:

    3.1XMPPRoster的激活
    /**
             *  XMPPRoster模块激活
             */
            self.rosterStorage = [XMPPRosterCoreDataStorage sharedInstance];
            self.roster = [[XMPPRoster alloc] initWithRosterStorage:self.rosterStorage];
            [self.roster activate:self.stream];
    
    3.2获取好友列表

    查询步骤:

    • 1.设置代理XMPPRosterDelegate,这是为了监听后面的好友请求
    • 2.通过XMPPRosterCoreDataStorage的数据库获得管理对象上下文
    • 3.设置请求实体对象
    • 4.设置查询条件
    • 5.排序
    • 6.执行请求NSFetchedResultsController(代理),
    • 7.缓存到本地刷新

    注意:设置查询条件的条件

    这里使用了一个类NSFetchedResultsController,是将查询和表结合的一种控件

    // 通常有两种方式,这里就采用这种方式,如有兴趣可以查阅相关资料
        XMPPManager *manager = [XMPPManager sharedmanager];
        [manager.roster addDelegate:self delegateQueue:dispatch_get_main_queue()];
        UserManager *user = [UserManager sharedmanager];
        // 通过XMPPRosterCoreDataStorage的数据库获得管理对象上下文
        NSManagedObjectContext *context = manager.rosterStorage.mainThreadManagedObjectContext;
        // 设置请求实体对象,在数据库中名为XMPPUserCoreDataStorageObject的一张表
        NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"XMPPUserCoreDataStorageObject"];
        // 设置谓词查询条件,用户名是自己的JID
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"streamBareJidStr=%@",user.jid];
        request.predicate = predicate;
        
        // 排序:按照用户名进行排序
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"displayName" ascending:YES]
        ;
        request.sortDescriptors = @[sort];
        
        _fetchedRequestC = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
        _fetchedRequestC.delegate = self;
    
        NSError *error = nil;
        if ([_fetchedRequestC performFetch:&error]) {
            NSLog(@"%@",error);
        }
        [self.friendsArray removeAllObjects];
        [self.friendsArray addObjectsFromArray:_fetchedRequestC.fetchedObjects];
        [self.tableView reloadData];
        
        for (XMPPUserCoreDataStorageObject *obj in self.friendsArray) {
            //NSLog(@"%@ ++ %@ ++ %@", obj.jidStr, obj.nickname, obj.displayName);
        }
    
    #pragma mark - NSFetchedResultsControllerDelegate
    // 代理方法,当数据发生变化时调用该方法
    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(nullable NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(nullable NSIndexPath *)newIndexPath {
        NSLog(@"数据发生变化");
        [self.friendsArray removeAllObjects];
        [self.friendsArray addObjectsFromArray:controller.fetchedObjects];
        for (XMPPUserCoreDataStorageObject *obj in self.friendsArray) {
            //NSLog(@"%@ -- %@ -- %@", obj.jidStr, obj.nickname, obj.displayName);
        }
        [self.tableView reloadData];
    }
    
    3.3添加好友

    注意:
    1.不能添加自己为好友
    2.不能添加已存在的好友

        if ([self.searchTextField.text isEqualToString:[UserManager sharedmanager].loginName]) {
            [self showAlert:@"不能添加自己为好友"];
            return;
        }
        
        NSString *jidStr = [NSString stringWithFormat:@"%@@%@",self.searchTextField.text,kHostName];
        XMPPJID *jid = [XMPPJID jidWithString:jidStr];
        
        XMPPManager *manager = [XMPPManager sharedmanager];
        if ([manager.rosterStorage userExistsWithJID:jid xmppStream:manager.stream]) {
            [self showAlert:@"不能重复添加好友"];
            return;
        }
        
        [manager.roster subscribePresenceToUser:jid];
        [self showAlert:@"已发送添加好友请求"];
    
    3.4删除好友

    注意:
    1.从服务器删
    2.从本地缓存删
    3.从表中删

            XMPPUserCoreDataStorageObject *friend = self.friendsArray[indexPath.row];
            // 从服务器删
            [[XMPPManager sharedmanager].roster removeUser:friend.jid];
            // 从数组缓存中删
            [self.friendsArray removeObject:friend];
            // 从表中删
            [tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section]] withRowAnimation:UITableViewRowAnimationFade];
    
    3.5监听好友请求

    注意:
    1.可接受
    2.可拒绝

        XMPPRoster *roster = [XMPPManager sharedmanager].roster;
        NSString *message = [NSString stringWithFormat:@"%@请求添加你为好友",presence.from.user];
        XIAlertView *alertView = [[XIAlertView alloc] initWithTitle:@"提示" message:message cancelButtonTitle:@"拒绝"];
        [alertView addDefaultStyleButtonWithTitle:@"接收" handler:^(XIAlertView *alertView, XIAlertButtonItem *buttonItem) {
            if (buttonItem == 0) {
                // 接受
                [roster rejectPresenceSubscriptionRequestFrom:presence.from];
            } else {
                 / /拒绝
                 [roster acceptPresenceSubscriptionRequestFrom:presence.from andAddToRoster:YES];
            }
            [alertView dismiss];
        }];
        [alertView show];
    

    未完待续...

    相关文章

      网友评论

      • 心语风尚:使用XMPPFramework开发即时通讯 这样是不是意味着用第三方的即时通讯 不是自己做的了 面试官说我们自己做即时通讯是什么意思
      • 鹿零9:大神,膜拜。。

      本文标题:(十二)即时通讯之XMPPFramework花名册

      本文链接:https://www.haomeiwen.com/subject/pkzwsttx.html