XMPPFramework iOS开发(六)好友列表

XMPPFramework iOS开发(六)好友列表

一、程序目标

XMPPFramework iOS开发(六)好友列表_第1张图片

本文主要介绍XMPPFramework下花名册的使用方法,实现的功能有:获取好友列表、添加好友、删除好友。

二、使用准备

2.1 花名册模块

和电子名片模块一样,获取好友列表同样需要在XMPPFramework.h中启用花名册模块,并在XMPP工具类中定义成员变量,为XMPPStream添加花名册模块拓展。

XMPPFramework.h 启用花名册模块:

//花名册模块
#import "XMPPRoster.h"
#import "XMPPRosterCoreDataStorage.h"

WCXMPPTool.h中定义成员变量:

//花名册模块
@property (nonatomic, strong, readonly) XMPPRoster *roster;
//花名册数据存储
@property (nonatomic, strong, readonly) XMPPRosterCoreDataStorage *rosterStorage;

WCXMPPTool.m,在setupStream方法中 为XMPPStream添加花名册模块拓展:

// 3.添加花名册模块
    if (_rosterStorage == nil) {
        _rosterStorage = [[XMPPRosterCoreDataStorage alloc] init];
        _roster = [[XMPPRoster alloc] initWithRosterStorage:_rosterStorage];
        [_roster activate:_xmppStream];
    }

程序从服务器中获取到好友列表后,会把数据保存到本地并生成一个sqlite文件。

2.2 释放资源

另外,在上一节没讲的是,程序退出后要释放相应的资源,在WCXMPPTool中增加以下内容:

- (void)teardownStream
{
    //移除代理
    [_xmppStream removeDelegate:self];

    //取消模块
    [_vCard deactivate];
    [_avatar deactivate];
    [_roster deactivate];

    //断开连接
    [_xmppStream disconnect];

    //清空资源
    _rosterStorage = nil;
    _roster = nil;
    _vCardStorage = nil;
    _vCard = nil;
    _avatar = nil;
    _xmppStream = nil;
}

- (void)dealloc
{
    [self teardownStream];
}

2.3 NSFetchedResultsController

@interface WCContactViewController () <NSFetchedResultsControllerDelegate>{
    NSFetchedResultsController *_resultContr;
}

@property (nonatomic, strong) NSArray *users;

@end

NSFetchedResultsController,官方解释是可以有效地管理从Core Data读取到的提供给UITableView对象的数据。

使用方法分为3步:
1. 配置一个request,指定要查询的数据库表
2. 至少为获取到的数据设置一个排序方法
3. 可以为数据设置过滤条件

除此之外,它还提供以下两个功能:
1. 监听和它关联的上下文(NSManagedObjectContext)的改变,并报告这些改变
2. 缓存结果,重新显示相同的数据的时候不需要再获取一遍

三、好友列表

3.1 获取好友列表

/** * 好友列表加载 */
- (void)loadUsers
{
    //显示好友数据(保存在XMPPRoster.sqlite)
    //1.上下文,关联XMPPRoster.sqlite
    NSManagedObjectContext *rosterContext = [[WCXMPPTool sharedWCXMPPTool].rosterStorage mainThreadManagedObjectContext];

    //2.请求查询哪张表
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"XMPPUserCoreDataStorageObject"];

    //设置排序
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"displayName" ascending:YES];
    request.sortDescriptors = @[sort];

    //过滤没有添加成功的好友
    //语法和sql一样
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"subscription != %@", @"none"];
    request.predicate = predicate;

    //3.执行请求
    //3.1创建结果控制器
    _resultContr = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:rosterContext sectionNameKeyPath:nil cacheName:nil];
    _resultContr.delegate = self;
    //3.2执行
    NSError *error = nil;
    [_resultContr performFetch:&error];
}

3.2 显示好友列表

#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _resultContr.fetchedObjects.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"users";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ID];
    }

    XMPPUserCoreDataStorageObject *user = _resultContr.fetchedObjects[indexPath.row];
    cell.textLabel.text = user.displayName;

    //标志用户是否在线
    //0:在线 1:离开 2:离线
    ZHLog(@"%@ 在线状态:%@", user.displayName, user.sectionNum);

    switch ([user.sectionNum integerValue]) {
        case 0:
            cell.detailTextLabel.text = @"在线";
            break;
        case 1:
            cell.detailTextLabel.text = @"离开";
            break;
        case 2:
            cell.detailTextLabel.text = @"离线";
            break;
        default:
            cell.detailTextLabel.text = @"其它";
            break;
    }

    //显示好友头像,一般情况下,程序启动时没有头像
    if (user.photo) {
        cell.imageView.image = user.photo;
    }else {
        NSData *data = [[WCXMPPTool sharedWCXMPPTool].avatar photoDataForJID:user.jid];
        cell.imageView.image = [UIImage imageWithData:data];
    }

3.3 刷新好友列表

#pragma mark 结果控制器代理方法
#pragma mark 数据库内容改变
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView reloadData];
}

四、添加/删除好友

4.1 删除好友

#pragma mark 实现此方法,左移cell就会出现删除按钮
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    XMPPUserCoreDataStorageObject *user = _resultContr.fetchedObjects[indexPath.row];
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [[WCXMPPTool sharedWCXMPPTool].roster removeUser:user.jid];
    }
}

4.2 添加好友

/** * 添加好友 */
- (IBAction)addContactBtnClick:(id)sender {


    NSString *user = self.textField.text;


    //不能添加自己为好友
    if ([user isEqualToString:[WCUser shareUser].loginAccount]) {
        [self showAlert:@"不能添加自己为好友!"];
        return;
    }

    //已存在的好友无需添加
    XMPPJID *userJid = [XMPPJID jidWithUser:user domain:[WCUser shareUser].domain resource:nil];
    BOOL isUserExiests = [[WCXMPPTool sharedWCXMPPTool].rosterStorage userExistsWithJID:userJid xmppStream:[WCXMPPTool sharedWCXMPPTool].xmppStream];
    if (isUserExiests) {
        [self showAlert:@"好友已经存在!"];
    }

    //subscribe是订阅的意思
    [[WCXMPPTool sharedWCXMPPTool].roster subscribePresenceToUser:userJid];
}

- (void)showAlert:(NSString *)message
{
    UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil];
    [av show];
}

五、跳转到聊天界面

聊天的功能在下一节讲,这里先把跳转到聊天界面的功能的代码贴上来

#pragma mark 点中进入聊天界面
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //把要聊天的好友的jid传过去
    XMPPJID *friendJid = [_resultContr.fetchedObjects[indexPath.row] jid];
    [self performSegueWithIdentifier:@"toChatVcSegue" sender:friendJid];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    id destVc = segue.destinationViewController;
    if ([destVc isKindOfClass:[WCChatViewController class]]) {
        WCChatViewController *chatVc = destVc;
        chatVc.friendJid = sender;
    }
}

六、收到好友添加申请

以下代码写在XMPPTool类里面。

6.1 使用准备

为roster设置几个属性

    //给xmppRoster添加代理
    [_roster addDelegate:self delegateQueue:dispatch_get_main_queue()];
    //设置好友同步策略,XMPP一旦连接成功,同步好友到本地
    [_roster setAutoFetchRoster:YES];
    //关掉自动接收好友请求,默认开启自动同意
    [_roster setAutoAcceptKnownPresenceSubscriptionRequests:NO];

添加autoPing模块


@property (nonatomic, strong, readonly) XMPPAutoPing *xmppAutoPing;

@property (nonatomic, strong) XMPPPresence *receivePresence;
    //6.autoPing模块
    _xmppAutoPing = [[XMPPAutoPing alloc] init];
    [_xmppAutoPing activate:_xmppStream];

    [_xmppAutoPing setPingInterval:1000];
    //来自普通的用户的请求一样会响应
    [_xmppAutoPing setRespondsToQueries:YES];

6.2 收到好友添加申请

#pragma mark =====好友添加模块=======
/** 收到出席订阅请求(代表对方想添加自己为好友) */
- (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence
{
    //添加好友一定会订阅对方,但是接受订阅不一定要添加对方为好友
    self.receivePresence = presence;

    //提示用户信息
    NSString *userName = presence.from.bare;
    NSString *message = [NSString stringWithFormat:@"【%@】想加你为好友", userName];
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:message delegate:self cancelButtonTitle:@"拒绝" otherButtonTitles:@"同意", nil];
    [alertView show];
}

6.3 处理好友添加请求

#pragma mark - 监听alert点击事件
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 0) { //拒绝
        [self.roster rejectPresenceSubscriptionRequestFrom:_receivePresence.from];
    } else {  //接受
        [self.roster acceptPresenceSubscriptionRequestFrom:_receivePresence.from andAddToRoster:YES];
    }
}

6.4 xmppRoster代理方法

- (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterPush:(XMPPIQ *)iq { ODLog(@"发送好友添加请求-->%@", iq); } #pragma mark 互为好友 - (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(DDXMLElement *)item { ODLog(@"互为好友-->%@, %@", item, [item attributeStringValueForName:@"jid"]); }

打印结果:

七、小结

XMPPFramework iOS开发(六)好友列表_第2张图片

XMPPFramework iOS开发(六)好友列表_第3张图片

以上。

你可能感兴趣的:(ios,Roster,XMPP,添加好友,花名册)