iOS XMPP Framework 06 - Roster 上

这一节我们为YDChat添加对Roster的支持,实现好友的添加和显示功能。XMPP框架在XMPPRoster类中已经支持了对roster的处理。在YDAppDelegate的setupStream方法中,我们已经构造并配置了一个xmppRoster的实例。XMPP框架还通过XMPPRosterCoreDataStorage类支持我们将好友列表写入内存、core data或者自定义的存储机制中。

autoFetchRoster标示应用程序在连接到服务器后会自动请求好友列表。

autoAcceptKnownPresenceSubscriptionRequests用于让应用程序只获取在线好友的信息,因为实际的好友列表可能很大,而用户只关心在线的好友。

    // Setup roster
    //
    // The XMPPRoster handles the xmpp protocol stuff related to the roster.
    // The storage for the roster is abstracted.
    // So you can use any storage mechanism you want.
    // You can store it all in memory, or use core data and store it on disk, or use core data with an in-memory store,
    // or setup your own using raw SQLite, or create your own storage mechanism.
    // You can do it however you like! It's your application.
    // But you do need to provide the roster with some storage facility.
    
    self.xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];
    //	xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] initWithInMemoryStore];
    
    self.xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:self.xmppRosterStorage];
    
    self.xmppRoster.autoFetchRoster = YES;
    self.xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;

显示好友列表

实现YDContactsViewController,继承于YDBaseViewController。这个类中,有一个UITableView用于显示好友列表。

#import "YDBaseViewController.h"

@interface YDContactsViewController : YDBaseViewController

@end

声明遵循以下代理协议

#import "YDContactsViewController.h"
#import <CoreData/CoreData.h>
#import "YDAppDelegate.h"
#import "DDLog.h"

@interface YDContactsViewController ()<NSFetchedResultsControllerDelegate,UITableViewDataSource,UITableViewDelegate,UIAlertViewDelegate>
{
    NSFetchedResultsController *fetchedResultsController;
}
@property (nonatomic,strong) UITableView *mtableView;
@end
实现viewDidLoad,创建UITableView并设置自己是其data source和代理

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor=[UIColor whiteColor];
    self.mtableView = [[UITableView alloc] initWithFrame:CGRectMake(0,86,ScreenWidth,ScreenHeight - 86-40) style:UITableViewStylePlain];

     self.mtableView .delegate=self;
     self.mtableView .dataSource=self;
     self.mtableView .rowHeight=38.0;
    
     self.mtableView .separatorStyle=UITableViewCellSeparatorStyleNone;
     self.mtableView .backgroundColor = [UIColor clearColor];
    [self.view addSubview:self.mtableView];
}
实现fetchResultController,用于从XMPPUserCoreDataStorage获取数据
- (NSFetchedResultsController *)fetchedResultsController
{
	if (fetchedResultsController == nil)
        {
		NSManagedObjectContext *moc = [[self appDelegate] managedObjectContext_roster];
		
		NSEntityDescription *entity = [NSEntityDescription entityForName:@"XMPPUserCoreDataStorageObject"
		                                          inManagedObjectContext:moc];
		
		NSSortDescriptor *sd1 = [[NSSortDescriptor alloc] initWithKey:@"sectionNum" ascending:YES];
		NSSortDescriptor *sd2 = [[NSSortDescriptor alloc] initWithKey:@"displayName" ascending:YES];
		
		NSArray *sortDescriptors = [NSArray arrayWithObjects:sd1, sd2, nil];
		
		NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
		[fetchRequest setEntity:entity];
		[fetchRequest setSortDescriptors:sortDescriptors];
		[fetchRequest setFetchBatchSize:10];
		
		fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
		                                                               managedObjectContext:moc
		                                                                 sectionNameKeyPath:@"sectionNum"
		                                                                          cacheName:nil];
		[fetchedResultsController setDelegate:self];
		
		
		NSError *error = nil;
		if (![fetchedResultsController performFetch:&error])
            {
			DDLogError(@"Error performing fetch: %@", error);
            }
        
        }
	
	return fetchedResultsController;
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
	[self.mtableView reloadData];
}
tableView相关的方法:


#pragma mark UITableViewCell helpers


- (void)configurePhotoForCell:(UITableViewCell *)cell user:(XMPPUserCoreDataStorageObject *)user
{
	// Our xmppRosterStorage will cache photos as they arrive from the xmppvCardAvatarModule.
	// We only need to ask the avatar module for a photo, if the roster doesn't have it.
	
	if (user.photo != nil)
        {
		cell.imageView.image = user.photo;
        }
	else
        {
		NSData *photoData = [[[self appDelegate] xmppvCardAvatarModule] photoDataForJID:user.jid];
        
		if (photoData != nil)
			cell.imageView.image = [UIImage imageWithData:photoData];
		else
			cell.imageView.image = [UIImage imageNamed:@"emptyavatar"];
        }
}


#pragma mark UITableView


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
	return [[[self fetchedResultsController] sections] count];
}

- (NSString *)tableView:(UITableView *)sender titleForHeaderInSection:(NSInteger)sectionIndex
{
	NSArray *sections = [[self fetchedResultsController] sections];
	
	if (sectionIndex < [sections count])
        {
		id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:sectionIndex];
        
		int section = [sectionInfo.name intValue];
		switch (section)
            {
                case 0  : return @"Available";
                case 1  : return @"Away";
                default : return @"Offline";
            }
        }
	
	return @"";
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex
{
	NSArray *sections = [[self fetchedResultsController] sections];
	
	if (sectionIndex < [sections count])
        {
		id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:sectionIndex];
		return sectionInfo.numberOfObjects;
        }
	
	return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	static NSString *CellIdentifier = @"Cell";
	
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
	if (cell == nil)
        {
		cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier:CellIdentifier];
        }
	
	XMPPUserCoreDataStorageObject *user = [[self fetchedResultsController] objectAtIndexPath:indexPath];
	
	cell.textLabel.text = user.displayName;
	[self configurePhotoForCell:cell user:user];
	
	return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    //Get our contact record
    XMPPUserCoreDataStorageObject *user = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    DDLogInfo(@"user %@",user.jidStr);
    
}
viewWillDisappear

- (void)viewWillDisappear:(BOOL)animated
{
	// do not disconnect to the sever when exit from contacts view controller
    //[[self appDelegate] disconnect];
	[[[self appDelegate] xmppvCardTempModule] removeDelegate:self];
	
	[super viewWillDisappear:animated];
}

此外还需要修改YDAppDelegate函数,实现通过点击侧边栏在HomeView和ContactsView之间的切换:

-(void)leftMenuSelectionItemClick:(YDMenuItem *)item
{
    
    if ([item.controllerTAG length]>0)
    {
        [self.container setMenuState:YDSLideMenuStateClosed];
        
        if ([item.controllerTAG isEqualToString:kMenuHomeTag])
        {
            //allocate the View Controller
            if (homeViewController == nil)
            {
                homeViewController = [[YDHomeViewController alloc]init];
            }
            [self.navigationController popViewControllerAnimated:YES];
            //[self.navigationController pushViewController:homeViewController animated:YES];
            
        }
        else if ([item.controllerTAG isEqualToString:kMenuContactsTag])
        {
            //allocate the View Controller
            contactsViewController = [[YDContactsViewController alloc]init];
            [self.navigationController popViewControllerAnimated:YES];
            [self.navigationController pushViewController:contactsViewController animated:YES];
            
        }
    }
}



程序执行效果如下:







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值