前言
这也是本人第一次琢磨关于即时通讯方面的内容,结合网上查看的相关资料搭建出来的仿微信小demo,如有意见请多多指教
具体项目可以在githubWeiChat下载进行查看,如若各位看官老爷觉得还可以请点star
**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];
未完待续...