_m_xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:_xmppRoomDatajid:RoomJID dispatchQueue:queue2 ];
那我这里就详细介绍一下各个参数该如何设置.
第一个参数,是XMPPRoomCoreDataStorage类型,他是为这个房间分配一个coredata的数据库,但由于我是用自己的数据库,所以就用
_xmppRoomData = [[XMPPRoomCoreDataStoragealloc] initWithInMemoryStore];
来实例化之。
第二个参数则是Room的JID这个需要自己分配,不能跟服务器已经有的JID重复。
第三个参数则是房间所在队列,此参数特别重要,请大家一定注意。xmpp的提供了一个IOS 的demo,此demo很大程度上误导了大家,因为他初始化queue都用的是
dispatch_get_main_queue()
这是主线程队列(没错就是管UI更新的那个),他可能是为了图写domo方便所以才用这个队列。但是实际的聊天软件,你敢在写主线程队列里面?一个也许还行,20个房间呢?程序根本就卡到爆。所以我建议大家重新新建一个串行队列
e.g :
queue2 =dispatch_queue_create("com.我的工程.RoomQueue",NULL); // 串行queue
你也许想问,为什么一定要用串行?并行为什么不行?因为,stream也是串行的,也是一条一条往服务器送。
注意事项:最好自己抽象一个RoomClass,一个聊天室就是一个RoomClass对象,这样可以方便管控房间消息和加入离开房间等。下面贴上我自己的RoomClass和初始化RoomClass方法:
RoomClass.h
//
// RoomClass.h
// MICI13
//
// Created by on 14-6-17.
// Copyright (c) 2014年 DoubleKill. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "XMPPFramework.h"
#import "XMPPRoom.h"
#import "CoreDataManager.h"
//#import "CentreControl.h"
#import "TFTimer.h"
@interface RoomClass :NSObject<XMPPRoomDelegate>{
NSTimer *RoomTimer;
XMPPStream *stream;
}
//#define kNofSingleMessage @"kNofSingleMessage"
//#define kNofRoomMessage @"kNofRoomMessage"
//#define kNofRoomDidJion @"kNofRoomDidJion"
//#define kNofRoomReceiveInvitation @"kNofRoomReceiveInvitation"
typedefvoid(^handler)(BOOL result,id obj) ;
@property (nonatomic,copy)handler RoomBlock;//
@property (nonatomic,strong) XMPPRoomCoreDataStorage *xmppRoomData;
@property (nonatomic,strong) XMPPRoom *m_xmppRoom;
@property (nonatomic,copy) NSString *Jid;
@property (nonatomic,assign) BOOL isCame;
@property (nonatomic,assign) BOOL isLoadHistory;
- (id)initWithJid:(NSString *)jid members:(NSMutableArray *)members stream:(XMPPStream*)xmppstream Finish:(handler)finished;
-(void)leaveRoom;
@end
//
// RoomClass.m
// MICI13
//
// Created by on 14-6-17.
// Copyright (c) 2014年 DoubleKill. All rights reserved.
//
#import "RoomClass.h"
@implementation RoomClass{
XMPPStream * m_stream;
NSMutableArray * members;
NSString *Roomjid;
NSDate *dateIn;
}
extern dispatch_queue_t queue2;
//
//NSString *const kXMPPmyJID = @"kXMPPmyJID";
//NSString *const kXMPPmyPassword = @"kXMPPmyPassword";
- (id)initWithJid:(NSString *)RoomJID members:(NSMutableArray *)member stream:(XMPPStream*)xmppstream Finish:(handler)finished
{
_RoomBlock = finished;
m_stream = xmppstream;
Roomjid = RoomJID;
members = member;
self = [superinit];
if (self) {
// Custom initialization
_xmppRoomData = [[XMPPRoomCoreDataStoragealloc] initWithInMemoryStore];
_m_xmppRoom = [[XMPPRoomalloc] initWithRoomStorage:_xmppRoomDatajid:[XMPPJIDjidWithString:RoomJID] dispatchQueue:queue2members:member];
[_m_xmppRoomactivate:xmppstream];
if ([_m_xmppRoom
preJoinWithNickname:[[NSUserDefaultsstandardUserDefaults] objectForKey:@"kXMPPmyJID"]])
{
// NSLog(@"room created RoomJid:%@",RoomJID);
NSXMLElement *xml = [[NSXMLElementalloc] initWithXMLString:@"<history maxstanzas='0'/>"error:nil];
// NSLog(@"room xml == {%@}",xml.XMLString);
[_m_xmppRoomjoinRoomUsingNickname:[[NSUserDefaultsstandardUserDefaults] objectForKey:@"kXMPPmyJID"]history:xml];
}
[_m_xmppRoomaddDelegate:selfdelegateQueue:queue2];
NSLog(@"init roomJID%@",RoomJID);
}
return self;
}
-(void)leaveRoom{
if (!_isCame) {
[RoomTimerpauseTimer];
}
[_m_xmppRoom leaveRoom];
[_m_xmppRoom deactivate];
//
[_m_xmppRoomremoveDelegate:selfdelegateQueue:queue2];
}
- (void)xmppRoomDidCreate:(XMPPRoom *)sender{
// NSLog(@"xmppRoomDidCreate~");
}
- (void)xmppRoom:(XMPPRoom *)sender didFetchConfigurationForm:(NSXMLElement *)configForm{
// NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender willSendConfiguration:(XMPPIQ *)roomConfigForm{
// NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender didConfigure:(XMPPIQ *)iqResult{
// NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender didNotConfigure:(XMPPIQ *)iqResult{
// NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoomDidJoin:(XMPPRoom *)sender{
NSLog(@"xmppRoomDidJoin~");
_isCame = YES;
_isLoadHistory =NO;
Group *group = [GroupGroupAtJid:Roomjid];
if (!(group.since.length >5) ) {
dateIn = [NSDatedate];
}
[RoomTimerpauseTimer];
_RoomBlock(YES,sender);
[[NSNotificationCenterdefaultCenter] postNotificationName:@"kNofRoomDidJion"object:nil];
XMPPJID *jid = [XMPPJIDjidWithString:[[NSUserDefaultsstandardUserDefaults] stringForKey:@"kXMPPmyJID"]];
NSString *Sjid =[[NSUserDefaultsstandardUserDefaults] stringForKey:@"kXMPPmyJID"];
//設置管理員
NSLog(@"edit==%@",[sendereditRoomPrivileges:[NSArrayarrayWithObjects:[XMPPRoomitemWithRole:@"moderator"jid:jid], nil]]);
//配置房間參數
NSXMLElement *roomConfigure = [[NSXMLElementalloc] initWithXMLString:[NSStringstringWithFormat:@"<x xmlns=\"jabber:x:data\" type=\"form\"><title>房间配置</title><instructions>已创建房间“xx”。要接受缺省配置,请单击“确定”按钮。或填写以下表单以完成设置:</instructions><field var=\"FORM_TYPE\" type=\"hidden\"><value>http://jabber.org/protocol/muc#roomconfig</value></field><field var=\"muc#roomconfig_roomname\" type=\"text-single\" label=\"房间名称\"><value>xx</value></field><field var=\"muc#roomconfig_roomdesc\" type=\"text-single\" label=\"描述\"><value>xx</value></field><field var=\"muc#roomconfig_changesubject\" type=\"boolean\" label=\"允许占有者更改主题\"><value>0</value></field><field var=\"muc#roomconfig_maxusers\" type=\"list-single\" label=\"最大房间占有者人数\"><option label=\"10\"><value>10</value></option><option label=\"20\"><value>20</value></option><option label=\"30\"><value>30</value></option><option label=\"40\"><value>40</value></option><option label=\"50\"><value>50</value></option><option label=\"无\"><value>0</value></option><value>30</value></field><field var=\"muc#roomconfig_presencebroadcast\" type=\"list-multi\" label=\"其 Presence 是 Broadcast 的角色\"><option label=\"主持者\"><value>moderator</value></option><option label=\"参与者\"><value>participant</value></option><option label=\"访客\"><value>visitor</value></option><value>moderator</value><value>participant</value><value>visitor</value></field><field var=\"muc#roomconfig_publicroom\" type=\"boolean\" label=\"列出目录中的房间\"><value>1</value></field><field var=\"muc#roomconfig_persistentroom\" type=\"boolean\" label=\"房间是持久的\"><value>1</value></field><field var=\"muc#roomconfig_moderatedroom\" type=\"boolean\" label=\"房间是适度的\"><value>0</value></field><field var=\"muc#roomconfig_membersonly\" type=\"boolean\" label=\"房间仅对成员开放\"><value>0</value></field><field type=\"fixed\"><value>注意:缺省情况下,只有管理员才可以在仅用于邀请的房间中发送邀请。</value></field><field var=\"muc#roomconfig_allowinvites\" type=\"boolean\" label=\"允许占有者邀请其他人\"><value>1</value></field><field var=\"muc#roomconfig_passwordprotectedroom\" type=\"boolean\" label=\"需要密码才能进入房间\"><value>0</value></field><field type=\"fixed\"><value>如果需要密码才能进入房间,则您必须在下面指定密码。</value></field><field var=\"muc#roomconfig_roomsecret\" type=\"text-private\" label=\"密码\" /><field var=\"muc#roomconfig_whois\" type=\"list-single\" label=\"能够发现占有者真实 JID的角色\"><option label=\"主持者\"><value>moderators</value></option><option label=\"任何人\"><value>anyone</value></option><value>anyone</value></field><field var=\"muc#roomconfig_enablelogging\" type=\"boolean\" label=\"登录房间对话\"><value>0</value></field><field var=\"x-muc#roomconfig_reservednick\" type=\"boolean\" label=\"仅允许注册的昵称登录\"><value>0</value></field><field var=\"x-muc#roomconfig_canchangenick\" type=\"boolean\" label=\"允许使用者修改昵称\"><value>1</value></field><field type=\"fixed\"><value>允许用户注册房间</value></field><field var=\"x-muc#roomconfig_registration\" type=\"boolean\" label=\"允许用户注册房间\"><value>1</value></field><field type=\"fixed\"><value>您可以指定该房间的管理员。请在每行提供一个 JID。</value></field><field var=\"muc#roomconfig_roomadmins\" type=\"jid-multi\" label=\"房间管理员\" /><field type=\"fixed\"><value>您可以指定该房间的其他拥有者。指定该房间的管理员。请在每行提供一个 JID。</value></field><field var=\"muc#roomconfig_roomadmins\" type=\"jid-multi\" label=\"房间管理员\" /><field type=\"fixed\"><value>您可以指定该房间的其他拥有者。\350\257请在每行提供一个 JID。</value></field><field var=\"muc#roomconfig_roomowners\" type=\"jid-multi\" label=\"房间拥有者\"><value>%@</value></field></x>",Sjid] error:Nil];
[senderconfigureRoomUsingOptions:roomConfigure];
[sender fetchConfigurationForm];
[senderfetchBanList];
[sender fetchMembersList];
[sender fetchModeratorsList];
}
- (void)xmppRoomDidLeave:(XMPPRoom *)sender{
[_m_xmppRoom leaveRoom];
[_m_xmppRoom deactivate];
_xmppRoomData =nil;
[_m_xmppRoomremoveDelegate:selfdelegateQueue:queue2];
}
- (void)xmppRoomDidDestroy:(XMPPRoom *)sender{
// NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender occupantDidJoin:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence{
// NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender occupantDidLeave:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence{
// NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender occupantDidUpdate:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence{
// NSLog(@"%s~~~",__FUNCTION__);
}
/**
* Invoked when a message is received.
* The occupant parameter may be nil if the message came directly from the room, or from a non-occupant.
**/
- (void)xmppRoom:(XMPPRoom *)sender didReceiveMessage:(XMPPMessage *)message fromOccupant:(XMPPJID *)occupantJID{
// NSLog(@"didReceiveMessage:%@",message);
NSError *error;//排除不符合格式的消息,免得奔溃
NSXMLElement *xml = [[NSXMLElementalloc] initWithXMLString:[NSStringstringWithFormat:@"<a>%@</a>",[messagebody]] error:&error];
if ([[xmlchildAtIndex:0]stringValue].length>2) {
return;
}
if ([Group isExist:sender.roomJID.bare]) {
}else{
return;
}
NSDate *dateNow = [NSDatedate];
float interval = [dateNow timeIntervalSinceDate:dateIn];
BOOL isRead = NO;
Group *group = [GroupGroupAtJid:Roomjid];
if (!(group.since.length >5)) {
// NSLog(@"groupId:%@",group.jid);
if (interval > 10) {//是新消息
// NSLog(@"是新消息");
isRead =NO;
[GroupupdateSince:RoomjidSince:@"111111"];
}else {//不是新消息
// NSLog(@"不是新消息");
isRead =YES;
dateIn = [NSDatedate];
}
}
if (![message.from.resourceisEqualToString:[[NSUserDefaultsstandardUserDefaults] objectForKey:@"kXMPPmyJID"]]) {
// NSLog(@"message.body:%@ jid:%@",message.body,sender.roomJID.bare);
switch ([[[xml childAtIndex:0]stringValue] intValue]) {
case 0://文本
{
if ([message.from.resourceisEqualToString:[[NSUserDefaultsstandardUserDefaults] objectForKey:@"kXMPPmyJID"]]) {//判断是否自己曾经发出去的
[MessageInsertMessage:[[xml childAtIndex:1]stringValue] Jid:sender.roomJID.barefrom:message.from.resourceisSendByMe:NOdate:[[xml childAtIndex:2]stringValue] type:MessageTypeMeisRead:isRead bigPic:nil];
}else{
[MessageInsertMessage:[[xml childAtIndex:1]stringValue] Jid:sender.roomJID.barefrom:message.from.resourceisSendByMe:NOdate:[[xml childAtIndex:2]stringValue] type:MessageTypeOtherisRead:isRead bigPic:nil];
}
}
break;
case 1://音频
{
if ([message.from.resourceisEqualToString:[[NSUserDefaultsstandardUserDefaults] objectForKey:@"kXMPPmyJID"]]) {
[MessageInsertMessage:[[xml childAtIndex:1]stringValue] Jid:[messagefrom].bare from:message.from.resourceisSendByMe:NOdate:[[xml childAtIndex:2]stringValue] type:AudioTypeMeisRead:isRead bigPic:nil];
}else{
[MessageInsertMessage:[[xml childAtIndex:1]stringValue] Jid:[messagefrom].bare from:message.from.resourceisSendByMe:NOdate:[[xml childAtIndex:2]stringValue] type:AudioTypeOtherisRead:isRead bigPic:nil];
}
}
break;
case 2://文件
{
}
break;
case 3://图片
{
NSString *bigPic;
if (xml.childCount>3) {
bigPic = [[xmlchildAtIndex:3]stringValue];
}else{
bigPic =nil;
}
if ([message.from.resourceisEqualToString:[[NSUserDefaultsstandardUserDefaults] objectForKey:@"kXMPPmyJID"]]) {
[MessageInsertMessage:[[xml childAtIndex:1]stringValue] Jid:[messagefrom].bare from:message.from.resourceisSendByMe:NOdate:[[xml childAtIndex:2]stringValue] type:ImageTypeMeisRead:isRead bigPic:bigPic];
}else {
[MessageInsertMessage:[[xml childAtIndex:1]stringValue] Jid:[messagefrom].bare from:message.from.resourceisSendByMe:NOdate:[[xml childAtIndex:2]stringValue] type:ImageTypeOtherisRead:isRead bigPic:bigPic];
}
}
break;
default:
break;
}
[[NSNotificationCenterdefaultCenter] postNotificationName:@"kNofSingleMessage"object:[NSDictionarydictionaryWithObject:message forKey:@"message"]];
}
}
- (void)xmppRoom:(XMPPRoom *)sender didFetchBanList:(NSArray *)items{
NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender didNotFetchBanList:(XMPPIQ *)iqError{
NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender didFetchMembersList:(NSArray *)items{
NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender didNotFetchMembersList:(XMPPIQ *)iqError{
NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender didFetchModeratorsList:(NSArray *)items{
// NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender didNotFetchModeratorsList:(XMPPIQ *)iqError{
// NSLog(@"%s~~~%@",__FUNCTION__,sender.roomJID.bare);
}
- (void)xmppRoom:(XMPPRoom *)sender didEditPrivileges:(XMPPIQ *)iqResult{
// NSLog(@"%s~~~",__FUNCTION__);
}
- (void)xmppRoom:(XMPPRoom *)sender didNotEditPrivileges:(XMPPIQ *)iqError{
// NSLog(@"%s~~~",__FUNCTION__);
}
@end
-(void)creatAllRoom{
for (RoomClass *roomin RoomArray) {
[roomleaveRoom];
}
[m_roomClassremoveAllObjects];
[RoomArrayremoveAllObjects];
for (Group * groupin [Group queryFromGroup:nil]) {
if ([group.hasJionedboolValue]) {
/**< 异步并回调主线程,常用ui更新*/
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT ,0), ^{
NSLog(@"yes creatAllRoom");
[[CentreControlsharedController] creatRoom:group.jid Nickname:[[NSUserDefaults standardUserDefaults] objectForKey:@"kXMPPmyJID"]members:NULL];
sleep(0.020);
dispatch_async(queue, ^{
// NSLog(@"to do with ui");
});
});
}
}
}
-(void)creatRoom:(NSString *)RoomJID Nickname:(NSString *)userNickName members:(NSMutableArray *)member Finish:(handler)finished{
RoomClass *room = [[RoomClassalloc] initWithJid:RoomJID members:memberstream:xmppStreamFinish:finished];
if (m_roomClass==nil) {
m_roomClass = [[NSMutableDictionaryalloc] init];
}
if (RoomArray ==nil || [RoomArraycount]==0) {
RoomArray = [[NSMutableArrayalloc] init];
}
if ([m_roomClassobjectForKey:RoomJID]!=nil ) {
}else{
[m_roomClasssetObject:room forKey:RoomJID];
[RoomArrayaddObject:room];
}
}