XMPPFramework的使用(二)---花名册

本人有若干成套学习视频, 可试看! 可试看! 可试看, 重要的事情说三遍 包含Java, 数据结构与算法, iOS, 安卓, python, flutter等等, 如有需要, 联系微信tsaievan.

XMPP 为我们提供了花名册模块, 即 XMPPRoster, 如果我们要写一个 APP, 用到花名册模块, 我们就必须添加这个模块,
这个模块的作用就是创建一个花名册的模型对象, 这个模型对象是基于 coreData 框架的,这样,我们就可以利用模型管理上下文给存储调度器发指令, 让存储调度器负责模型的存储.

我们将这个模块在 xmppStream 中激活之后, 那么所有关于presence 和 iq 的节点都会转化成花名册对象存储在沙盒中.

然后控制器获取数据之后就能在 View 上展示出来

XMPPFramework的使用(二)---花名册_第1张图片
xmpp 数据交互
  • 首先, 我们为 XMPPManager 创建一个分类, 即花名册分类, 在这个分类的方法中我们做三件事情
    1.初始化花名册模块
    2.为花名册模块设置属性及代理
    3.在 xmppStream 中激活花名册模块
YFXMPP+ Roster 分类
#pragma mark *** 添加花名册模块 ***
- (void)addRosterModule
{
     /* 1. 初始化 */
    self.xmppRoster = [[XMPPRoster alloc]initWithRosterStorage:[XMPPRosterCoreDataStorage sharedInstance] dispatchQueue:dispatch_get_main_queue()];
    
     /* 2. 配置属性 */
     /* 自动接收别人添加好友的请求 */
    self.xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;
    
     /* 当 xmpp 流断开时,自动清除花名册资源 */
    self.xmppRoster.autoClearAllUsersAndResources = YES;
    
     /* 自动查询花名册 */
    self.xmppRoster.autoFetchRoster = YES;
    
     /* 3. 设置代理 */
    [self.xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];
    
     /* 4. 激活 */
    
    [self.xmppRoster activate:self.xmppstream];
    
     /* 5. 手动获取花名册列表 */
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.xmppRoster fetchRoster];
    });
}

这样,我在 xmppStream 懒加载之后就添加成功了花名册模块,一旦 xmppStream 流中返回了添加好友, 或者好友关系变更等信息时, 就会走XMPPRosterDelegate 代理 API 回调

#pragma mark *** XMPPRosterDelegate 代理 API 回调 ***
 /* 开始获取花名册 */
- (void)xmppRosterDidBeginPopulating:(XMPPRoster *)sender withVersion:(NSString *)version
{
    
}

 /* 结束获取花名册 */
- (void)xmppRosterDidEndPopulating:(XMPPRoster *)sender
{
    
}

 /* 接收到好友请求 */
- (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence
{
    if (self.rosterReceiveBlock) {
        self.rosterReceiveBlock(presence);
    }
}

 /* 获取到每一个花名册好友 */
- (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(DDXMLElement *)item
{
    
}

 /* 好友关系变更 */
- (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterPush:(XMPPIQ *)iq
{
    if (self.rosterChangeBlock) {
        self.rosterChangeBlock(iq);
    }
}

如以上代码所示, 在接收到好友请求或者好友关系变更时, 在这个代理方法里我可以完成一个 block 回调, 在这个 block 中,去完成 fetchResultsController的 performFetch, 这样就能够实时拿到最新的数据

联系人控制器的代码
#pragma mark *** 视图的生命周期 ***

- (void)viewDidLoad {
    [super viewDidLoad];
    self.hidesBottomBarWhenPushed = YES;
    __weak typeof(self)weakSelf = self;
    kYFXMPPManager.rosterReceiveBlock = ^(XMPPPresence *presence){
        [kYFXMPPManager.xmppRoster acceptPresenceSubscriptionRequestFrom:presence.from andAddToRoster:YES];
        [weakSelf updateData];
    };
    
    kYFXMPPManager.rosterChangeBlock = ^(XMPPIQ *iq){
        [weakSelf updateData];
    };
}

// -------- 更新数据 --------
- (void)updateData
{
    /* 养成良好的习惯, 在 block 之前将 self 转化成 weakSelf, 避免循环引用 */
    __weak typeof(self)weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [weakSelf.fetchResultsController performFetch:nil];
    });
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [weakSelf.tableView reloadData];
    });
}

可以看出, 在更新数据的操作里, 我们先去获取数据,然后刷新 tableView
当然这一切都有依赖于NSFetchedResultsController这个神器

#pragma mark *** Getter & Setter ***
- (NSFetchedResultsController *)fetchResultsController
{
    if (!_fetchResultsController) {
        
        /* 1. 创建查询请求 */
        NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"XMPPUserCoreDataStorageObject"];
        /* 2. 设置查询请求的属性 */
        /* note: 设置排序器,否则程序会崩溃 */
        fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"jidStr" ascending:YES]];
        
        /* 设置好友关系为 both */
        fetchRequest.predicate = [NSPredicate predicateWithFormat:@"subscription == 'both'"];
        /**
         * 第一个参数:查询请求
         * 第二个参数:管理对象上下文
         * 第三个参数:分组依据
         * 第四个参数:缓存名字
         */
        _fetchResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest: fetchRequest managedObjectContext:[XMPPRosterCoreDataStorage sharedInstance].mainThreadManagedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
        /* 3. 执行查询 */
        [_fetchResultsController performFetch:nil];
        
//        /* 4. 控制台输出查询结果 */
//        for (XMPPUserCoreDataStorageObject *objc in self.fetchResultsController.fetchedObjects) {
//            NSLog(@"%@",objc);
//        }
        /* 5. 刷新 tableView */
        [self.tableView reloadData];
    }
    return _fetchResultsController;
}

当NSFetchedResultsController获取到数据之后, 展示数据就不是什么难事了. 花名册就很容易做出来了.

PS. 本人有若干成套学习视频, 包含Java, 数据结构与算法, iOS, 安卓, python, flutter等等, 如有需要, 联系微信tsaievan.

你可能感兴趣的:(XMPPFramework的使用(二)---花名册)