IOS:Can';t使用XMPP框架验证我的JabberID

IOS:Can';t使用XMPP框架验证我的JabberID,ios,objective-c,xmppframework,Ios,Objective C,Xmppframework,我只是在这里学习了这个教程(),但是我很难让这个应用程序正常工作 我正在使用XMPPFramework 3.5连接到一个本地XMPP服务器(Ejabberd 2.1.8)(因为教程有点旧,我决定使用以前的版本),我看不到任何联系人,但应用程序似乎运行良好,直到达到此方法的最后一行: - (void)xmppStreamDidConnect:(XMPPStream *)sender { // connection to the server successful isOpen =

我只是在这里学习了这个教程(),但是我很难让这个应用程序正常工作

我正在使用XMPPFramework 3.5连接到一个本地XMPP服务器(Ejabberd 2.1.8)(因为教程有点旧,我决定使用以前的版本),我看不到任何联系人,但应用程序似乎运行良好,直到达到此方法的最后一行:

- (void)xmppStreamDidConnect:(XMPPStream *)sender {

    // connection to the server successful
    isOpen = YES;
    NSError *error = nil;

    [ [self xmppStream] authenticateWithPassword:password error:&error ];

}
以下是错误:

2014-04-21 18:16:36.485 JabberClient[3295:207] -[JabberClientAppDelegate xmppStream]: unrecognized selector sent to instance 0x6c3fd30
2014-04-21 18:16:36.486 JabberClient[3295:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[JabberClientAppDelegate xmppStream]: unrecognized selector sent to instance 0x6c3fd30'
*** First throw call stack:
(0x1c64052 0x1f36d0a 0x1c65ced 0x1bcaf00 0x1bcace2 0x2da2 0x1bca51d 0x1bca437 0x1bf549a 0x6f13e 0x1a7f445 0x1a814f0 0x1b9b833 0x1b9adb4 0x1b9accb 0x2154879 0x215493e 0x876a9b 0x265d 0x25d5)
terminate called throwing an exceptionCurrent language:  auto; currently objective-c
(gdb) 
我可以看到Ejabberd正在接收连接,但我猜在用户通过身份验证之前,它不会让我呈现联系人列表:

=INFO REPORT==== 2014-04-21 18:16:36 ===
I(<0.383.0>:ejabberd_listener:281) : (#Port<0.495>) Accepted connection {{127,0,0,1},51937} -> {{127,0,0,1},5222}
=信息报告===2014-04-21 18:16:36===
I(:ejabberd_listener:281):(#端口)接受连接{{127,0,0,1},51937}->{127,0,0,1},5222}
我找不到任何资源为我指明正确的方向,有什么想法吗

--更新

这是执行此代码的类:

@interface JabberClientAppDelegate : NSObject <UIApplicationDelegate> {
        UIWindow *window;
        JabberClientViewController *viewController;
        XMPPStream *xmppStream;     
        NSString *password;
        BOOL isOpen;

    __weak NSObject  *_chatDelegate;
    __weak NSObject  *_messageDelegate;
}
@接口JabberClientAppDelegate:NSObject{
UIWindow*窗口;
JabberClientViewController*viewController;
XMPPStream*XMPPStream;
NSString*密码;
布尔等参;
__弱NSObject*\u chatDelegate;
__弱NSObject*_messageDelegate;
}

您的问题可能是xmppStream变得nil。为XMPP使用以下自定义代码

MessageManager.h

//  Created by Deepak MK.
//  Copyright © 2015 mindShiftApps. All rights reserved.
//

#import <UIKit/UIKit.h>

#import "XMPP.h"
#import <CoreData/CoreData.h>
#import "XMPPFramework.h"
#import "XMPPMessageDeliveryReceipts.h"
#import "XMPPLastActivity.h"
#import "XMPPRosterMemoryStorage.h"
#import "XMPPRoomMemoryStorage.h"
#import "XMPPvCardCoreDataStorage.h"
#import "XMPPvCardTemp.h"
/**
 message manager class manage all message sequence.
 */
@interface MessageManager : NSObject
{

    XMPPStream                                  *xmppStream;

    NSString                                    *password;

    BOOL                                        isOpen;

    BOOL                                        isRegistering;

    id                                          _delgate;

    XMPPRosterCoreDataStorage                    *xmppRosterStorage;

    XMPPRoster                                           *xmppRoster;

    XMPPvCardCoreDataStorage* xmppvCardStorage;
    XMPPvCardTempModule*xmppvCardTempModule;



}

+ (MessageManager *) sharedMessageHandler;

/**
 The stream varible for connecting stream
 */

@property (nonatomic, readonly) XMPPStream          *xmppStream;

/**
 XMPPRoster  varible
 */
@property (nonatomic, strong,readonly) XMPPRoster *xmppRoster;

/**
 XMPPRosterCoreDataStorage  varible 
 */
@property (nonatomic, strong,readonly) XMPPRosterCoreDataStorage *xmppRosterStorage;

/**
 XMPPRoom  varible
 */
@property (nonatomic, strong, readonly)  XMPPRoom *xmppRoom;


/**
 Setting of delegate
 @param delegate class delegate
 */
- (void) setdelegate:(id)delegate;

/**
 Return of delegate
 */
- (id)   delegate;

/**
 connecting stream of Xmpp server
 */

- (void) setupStream;

/**
 Connect user to Xmpp server
 @param jabberID    login user name
 @param myPassword  login password
 */
- (BOOL)connectWithUserId:(NSString*)jabberID withPassword:(NSString*)myPassword;

/**
 Connect user to Xmpp server
 @param userName    login user name
 @param myPassword  login password
 */
- (void) authenticateUserWIthUSerName:(NSString*)userName withPassword:(NSString*)myPassword;


/**
 disconnect user from Xmpp server
 */
- (void) disconnect;

/**
 changes the presence to online
 */
- (void) goOnline;

/**
 changes the presence to offline
 */
- (void) goOffline;

/**
 Register new user to xmpp server
 @param userName    new user name
 @param _password   new password
 @param EmailId     new email id
 */
- (void)registerStudentWithUserName:(NSString *)userName withPassword:(NSString *)_password withEmailId:(NSString *)EmailId;


/**
 send message to other user with content
 @param toAdress destination address
 @param content  content of message
 */
- (BOOL)sendMessageTo:(NSString*)toAdress withContents:(NSString*)content;



/**
 This method is used for sending subscribe invitation to user
 @param userID destination address
 */
- (void) sendSubscribeMessageToUser:(NSString*)userID;


/**
 This method is used for setting substate of presence
 @param subState substate of user
 */
- (void) presenceWithStubState:(NSString*)subState;


/**
 This method is used to create new room
 @param ChatRoomJID New room name
 */
- (void) setUpRoom:(NSString *)ChatRoomJID;


/**
 This method is used to destroyRoom
 */
- (void) destroyCreatedRoom;

/**
 This method is used to send message to group
 */
- (BOOL)sendGroupMessageWithBody:(NSString*)_body;



- (void) requestAllMesssage;

@end





/**
 Set of methods to be implemented to act as a restaurant patron
 */
@protocol MessageManagerDelegate <NSObject>

/**
 Methods to be get state of stream
 */
- (void) didGetStreamState:(BOOL)state;

/**
 Methods to be get state of Authentication
 */

- (void) didGetAuthenticationState:(BOOL)state;

/**
 Methods to be get state of registration
 */

- (void) didGetRegistrationState:(BOOL)state WithErrorMessage:(NSString*)errorMessage;

/**
 Methods to get recieved message
 */

- (void) didReceiveMessageWithBody:(NSString *) body;


/**
 Methods to get presence of other user
 */
- (void) didRecievePresence:(NSString*)state withUserName:(NSString*)userName WithSubState:(NSString*)subState;


/**
 Methods to get event of user joined room
 */
- (void) didCreatedOrJoinedRoomWithCreatedRoomName:(NSString*)_roomName;


- (void) didGetUserJoinedToRoomORLeaveRoomWithName:(NSString*)_userName WithPresence:(NSString*)presence;
@end
//由Deepak MK创建。
//版权所有©2015 Mindshiftaps。版权所有。
//
#进口
#导入“XMPP.h”
#进口
#导入“XMPPFramework.h”
#导入“XMPPMessageDeliveryReceipts.h”
#导入“XMPPLastActivity.h”
#导入“XMPPRosterMemoryStorage.h”
#导入“xmppromemorystorage.h”
#导入“XMPPvCardCoreDataStorage.h”
#导入“XMPPvCardTemp.h”
/**
消息管理器类管理所有消息序列。
*/
@接口消息管理器:NSObject
{
XMPPStream*XMPPStream;
NSString*密码;
布尔等参;
布尔正在注册;
迪尔盖特;
XMPPRosterCoreDataStorage*xmppRosterStorage;
XMPPRoster*XMPPRoster;
XMPPvCardCoreDataStorage*xmppvCardStorage;
XMPPvCardTempModule*XMPPvCardTempModule;
}
+(MessageManager*)sharedMessageHandler;
/**
用于连接流的流是可变的
*/
@属性(非原子,只读)XMPPStream*XMPPStream;
/**
XMPPRoster变量
*/
@属性(非原子、强、只读)XMPPRoster*XMPPRoster;
/**
XMPPRosterCoreDataStorage变量
*/
@属性(非原子、强、只读)XMPPRosterCoreDataStorage*xmppRosterStorage;
/**
XMPPRoom变量
*/
@属性(非原子、强、只读)XMPPRoom*XMPPRoom;
/**
委托的设置
@参数委托类委托
*/
-(void)setdelegate:(id)delegate;
/**
代表的返回
*/
-(id)代表;
/**
Xmpp服务器的连接流
*/
-(void)流;
/**
将用户连接到Xmpp服务器
@param jabberID登录用户名
@参数myPassword登录密码
*/
-(BOOL)connectWithUserId:(NSString*)jabberID with password:(NSString*)myPassword;
/**
将用户连接到Xmpp服务器
@参数用户名登录用户名
@参数myPassword登录密码
*/
-(void)authenticateUserWIthUSerName:(NSString*)userName withPassword:(NSString*)myPassword;
/**
断开用户与Xmpp服务器的连接
*/
-(无效)断开连接;
/**
将状态更改为联机
*/
-(无效)goOnline;
/**
将状态更改为脱机
*/
-(无效)鹅掌线;
/**
向xmpp服务器注册新用户
@参数用户名新用户名
@参数密码新密码
@参数EmailId新电子邮件id
*/
-(void)registerStudentWithUserName:(NSString*)userName withPassword:(NSString*)U password withEmailId:(NSString*)EmailId;
/**
将包含内容的消息发送给其他用户
@参数目标地址
@消息的参数内容
*/
-(BOOL)sendMessageTo:(NSString*)以使用内容:(NSString*)内容进行处理;
/**
此方法用于向用户发送订阅邀请
@参数用户标识目标地址
*/
-(void)sendSubscribeMessageToUser:(NSString*)用户ID;
/**
此方法用于设置存在的子状态
@用户的param subState subState
*/
-(void)presenceWithStubState:(NSString*)子状态;
/**
此方法用于创建新房间
@param聊天室jid新聊天室名称
*/
-(无效)设置室:(NSString*)聊天室JID;
/**
这种方法是用来破坏房间的
*/
-(无效)销毁或销毁文件;
/**
此方法用于向组发送消息
*/
-(BOOL)sendGroupMessageWithBody:(NSString*)\u body;
-(无效)请求所有信息;
@结束
/**
作为餐厅顾客实施的一套方法
*/
@协议MessageManagerDelegate
/**
要获取流状态的方法
*/
-(void)didGetStreamState:(BOOL)状态;
/**
要获取身份验证状态的方法
*/
-(void)didGetAuthenticationState:(BOOL)状态;
/**
要获取注册状态的方法
*/
-(void)didGetRegistrationState:(BOOL)状态信息:(NSString*)错误信息;
/**
获取已接收消息的方法
*/
-(void)didReceiveMessageWithBody:(NSString*)body;
/**
方法来获取其他用户的存在
*/
-(void)DiReceivePresence:(NSString*)状态为用户名:(NSString*)用户名为子状态:(NSString*)子状态;
/**
获取用户加入房间的事件的方法
*/
-(void)didCreatedOrJoinedRoomWithCreatedRoomName:(NSString*)\u roomName;
-(void)DidgetUserJoinedtoromorleAveroomWithName:(NSString*)_用户名WithPresence:(NSString*)presence;
@结束
MessageManager.m

#import "MessageManager.h"

#import "DDLog.h"
#import "DDTTYLogger.h"
#import <CFNetwork/CFNetwork.h>
#if DEBUG
static const int ddLogLevel = LOG_LEVEL_VERBOSE;
#else
static const int ddLogLevel = LOG_LEVEL_INFO;
#endif


@interface MessageManager()


@end

static MessageManager *sharedMessageHandler = nil;

@implementation MessageManager

@synthesize xmppStream;
@synthesize xmppRoster;
@synthesize xmppRosterStorage;
@synthesize xmppRoom;

#pragma mark - self class Delegate
- (void) setdelegate:(id)delegate
{
    _delgate= delegate;
}
- (id)   delegate
{
    return _delgate;
}



#pragma  mark - custom Functions
+ (MessageManager *) sharedMessageHandler
{

    if (sharedMessageHandler == nil)
    {
        sharedMessageHandler = [[super allocWithZone:NULL] init];
    }

    return sharedMessageHandler;
}

+ (id)allocWithZone:(NSZone *)zone {

    return [self sharedMessageHandler];
}

- (id)copyWithZone:(NSZone *)zone {

    return self;
}


#pragma mark - connection setup Functions

/**
 This fuction is used to setup XMPP Stream
 */
- (void)setupStream
{

    // Setup xmpp stream
    //
    // The XMPPStream is the base class for all activity.
    // Everything else plugs into the xmppStream, such as modules/extensions and delegates.

    xmppStream = [[XMPPStream alloc] init];
    [xmppStream setHostName:kBaseXMPPURL];
    [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];

}

/** 
 This fuction is used to Connect XMPP With userId and Password 
 */
- (BOOL)connectWithUserId:(NSString*)jabberID withPassword:(NSString*)myPassword
{

    [self setupStream];

    isRegistering=NO;

    if (![xmppStream isDisconnected]) {
        return YES;
    }


    if (jabberID == nil || myPassword == nil) {

        return NO;
    }

    [xmppStream setMyJID:[XMPPJID jidWithString:jabberID]];
    password = myPassword;

    NSError *error = nil;
    if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error])
    {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error"
                                                            message:[NSString stringWithFormat:@"Can't connect to server %@", [error localizedDescription]]
                                                           delegate:nil
                                                  cancelButtonTitle:@"Ok" 
                                                  otherButtonTitles:nil];
        [alertView show];


        return NO;
    }

    return YES;
}


- (void) authenticateUserWIthUSerName:(NSString*)userName withPassword:(NSString*)myPassword
{

    if ([xmppStream isConnected])
    {
        NSError*error =nil;
        [xmppStream setMyJID:[XMPPJID jidWithString:userName]];
        [xmppStream authenticateWithPassword:myPassword error:&error];

    }
    else
    {
        [self connectWithUserId:userName withPassword:myPassword];
    }

}


#pragma mark ---Delegate of Connect
/**
 This fuction is called when stream is connected
 */
- (void)xmppStreamDidConnect:(XMPPStream *)sender {

    isOpen = YES;
    NSError *error = nil;

    NSLog(@"Stream Connected");
    if (!isRegistering)
    {
        if([[self delegate] respondsToSelector:@selector(didGetStreamState:)])
        {
            [[self delegate]didGetStreamState:YES];
        }

        [xmppStream authenticateWithPassword:password error:&error];
    }
    else
    {
        [xmppStream registerWithPassword:password error:&error];
    }


}

/**
 This fuction is called when User is Authenticated
 */
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {

    [self goOnline];
    NSLog(@"Stream Authenticated");
    if([[self delegate] respondsToSelector:@selector(didGetAuthenticationState:)])
    {
        [[self delegate]didGetAuthenticationState:YES];
    }



    if ([xmppStream isAuthenticated]) {
        NSLog(@"authenticated");
        xmppvCardStorage = [[XMPPvCardCoreDataStorage alloc] initWithInMemoryStore];
        xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage];
        [xmppvCardTempModule activate:[self xmppStream]];
        [xmppvCardTempModule addDelegate:self delegateQueue:dispatch_get_main_queue()];
        [xmppvCardTempModule fetchvCardTempForJID:[sender myJID] ignoreStorage:YES];
    }

}

- (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule didReceivevCardTemp:(XMPPvCardTemp *)vCardTemp forJID:(XMPPJID *)jid{


    NSLog(@"Delegate is called");
    XMPPvCardTemp *vCard = [xmppvCardStorage vCardTempForJID:jid xmppStream:xmppStream];
    NSLog(@"Stored card: %@",vCard);
    NSLog(@"%@", vCard.description);
    NSLog(@"%@", vCard.name);
    NSLog(@"%@", vCard.emailAddresses);
    NSLog(@"%@", vCard.formattedName);
    NSLog(@"%@", vCard.givenName);
    NSLog(@"%@", vCard.middleName);

}

/**
 This fuction is called when User is  not Authenticated
 */
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
    NSLog(@"Not Authenticated");

    if([[self delegate] respondsToSelector:@selector(didGetAuthenticationState:)])
    {
        [[self delegate]didGetAuthenticationState:NO];
    }
}


#pragma mark - Stream disconnection

/**
 This fuction is used to disconnet user
 */
- (void)disconnect
{
    [self goOffline];
    [xmppStream disconnect];
}

#pragma mark ---Delegate of disconnect
/**
 This fuction is called when stream is disConnected
 */
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{
    NSLog(@"Stream Disconnected");
    if([[self delegate] respondsToSelector:@selector(didGetStreamState:)])
    {
        [[self delegate]didGetStreamState:NO];
    }
}




#pragma mark - setting presence

/** 
 This fuction is used change the presence to online 
 */
- (void)goOnline
{
    XMPPPresence *presence = [XMPPPresence presence];
    [xmppStream sendElement:presence];
}

/**
 This fuction is used change the presence to Ofline 
 */
- (void)goOffline
{
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
    [xmppStream sendElement:presence];
}


/**
 This fuction is used change the presence substate
 */
- (void) presenceWithStubState:(NSString*)subState
{
    XMPPPresence *presence = [XMPPPresence presence];// type="available" is implicit

    NSXMLElement *status = [NSXMLElement elementWithName:@"status"];
    [status setStringValue:subState];
    [presence addChild:status];

    [xmppStream sendElement:presence];
}

/**
 This fuction is called when other user state is changed
 */
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
    DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [presence fromStr]);


    NSString *presenceType = [presence type];            // online/offline
    NSString *myUsername = [[sender myJID] user];
    NSString *presenceFromUser = [[presence from] user];
    NSString* presenceState= [presence status];

    NSLog(@"%@  is %@ state %@",presenceFromUser,presenceType,presenceState);

    if (![presenceFromUser isEqualToString:myUsername])
    {

        if ([presenceType isEqualToString:@"available"])
        {
            if([[self delegate] respondsToSelector:@selector(didRecievePresence:withUserName:WithSubState:)])
            {
                [[self delegate] didRecievePresence:presenceType withUserName:presenceFromUser WithSubState:presenceState];
            }

        }

        else if  ([presenceType isEqualToString:@"unavailable"]) {

             if([[self delegate] respondsToSelector:@selector(didRecievePresence:withUserName:WithSubState:)])
             {
                 [[self delegate] didRecievePresence:presenceType withUserName:presenceFromUser WithSubState:presenceState];
             }

        }
        else if  ([presenceType isEqualToString:@"subscribe"])
        {

            [xmppRoster subscribePresenceToUser:[presence from]];
            [self goOnline];
        }
        else if  ([presenceType isEqualToString:@"subscribed"])
        {
            [xmppRoster subscribePresenceToUser:[presence from]];
        }

    }
    if (xmppRoom)
    {
        [xmppRoom fetchMembersList];
    }


}

#pragma mark - subscription
- (void) sendSubscribeMessageToUser:(NSString*)userID
{
    XMPPJID* jbid=  [XMPPJID jidWithString:userID];
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"subscribe" to:jbid];
    [xmppStream sendElement:presence];
}


#pragma mark - XMPP delegates
/**
 This fuction is called when new IQ is received 
 */
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq {

    return NO;

}



#pragma mark - RegistrationFunction

/**
 This fuction is user to retister new user
   if stream is connected the it will directly call registeration function
    otherwise it will connect stream and then call registeration process 
 */

- (void)registerStudentWithUserName:(NSString *)userName withPassword:(NSString *)_password withEmailId:(NSString *)EmailId
{

    if (xmppStream==nil)
    {
        [self setupStream];
    }


    [xmppStream setMyJID:[XMPPJID jidWithString:userName]];
    NSLog(@"Attempting registration for username %@",xmppStream.myJID.bare);
    password=_password;
    NSError *error = nil;
    BOOL success;

    if(![ xmppStream isConnected])
    {
         success = [[self xmppStream] connectWithTimeout:XMPPStreamTimeoutNone error:&error];
        isRegistering=YES;
    }
    else
    {
        success = [[self xmppStream] registerWithPassword:_password error:&error];
    }

    if (success)
    {
        NSLog(@"succeed ");
        isRegistering=YES;
    }
    else
    {
        if([[self delegate] respondsToSelector:@selector(didGetRegistrationState:WithErrorMessage:)])
        {
            [[self delegate]didGetRegistrationState:YES WithErrorMessage:@"Stream not connected"];
        }
    }

}

#pragma mark ---delegates of registrtaion


/**
 This fuction is called when new user is registered 
 */
- (void)xmppStreamDidRegister:(XMPPStream *)sender{




    if([[self delegate] respondsToSelector:@selector(didGetRegistrationState:WithErrorMessage:)])
    {
        [[self delegate]didGetRegistrationState:YES WithErrorMessage:@"Registration with XMPP Successful!"];
    }


}


/**
 This fuction is called when registeration process failed 
 */
- (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error{

//    DDXMLElement *errorXML = [error elementForName:@"error"];
//    NSString *errorCode  = [[errorXML attributeForName:@"code"] stringValue];

//    NSString *regError = [NSString stringWithFormat:@"ERROR :- %@",error.description];
//    
//    
//    if([errorCode isEqualToString:@"409"])
//    {
//        regError=@"Username Already Exists!";
//    }
//    else
//    {
//        regError= @"Server not connected";
//    }
    if([[self delegate] respondsToSelector:@selector(didGetRegistrationState:WithErrorMessage:)])
    {
        [[self delegate]didGetRegistrationState:NO WithErrorMessage:@"Username Already Exists!"];
    }

}



#pragma mark - send  and recieve message
/**
 This fuction is used to send message to other user with contents of body
 */



//-(void)sendMessageTo:(NSString*)toAdress withContents:(NSString*)messageStr
//{
//    
//    
//    if([messageStr length]> 0)
//    {
//        
//        NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
//        [body setStringValue:messageStr];
//        
//        NSXMLElement *message = [NSXMLElement elementWithName:@"message"];
//        [message addAttributeWithName:@"type" stringValue:@"chat"];
//        [message addAttributeWithName:@"to" stringValue:toAdress];
//        [message addChild:body];
//        
//        [self.xmppStream sendElement:message];
//    }
//}



- (BOOL)sendMessageTo:(NSString*)toAdress withContents:(NSString*)content
{

    if([content length]> 0)
    {

        NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
        [body setStringValue:content];

        NSXMLElement *message = [NSXMLElement elementWithName:@"message"];
        [message addAttributeWithName:@"type" stringValue:@"chat"];
        [message addAttributeWithName:@"to" stringValue:toAdress];
        [message addChild:body];

        [self.xmppStream sendElement:message];
    }
    return YES;
}

#pragma mark  recieve message
/**
 This fuction is called when new message arrived
 */

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);

    // A simple example of inbound message handling.
    if ([message body])
    {
        NSString *body = [[message elementForName:@"body"] stringValue];
        if([[self delegate] respondsToSelector:@selector(didReceiveMessageWithBody:)])
        {
            [[self delegate] didReceiveMessageWithBody:body];
        }

    }
}



#pragma mark - create new room

/**
 This fuction is used to setup room with roomId
 */
-(void)setUpRoom:(NSString *)ChatRoomJID
{
    if (!ChatRoomJID)
    {
        return;
    }
    // Configure xmppRoom
    XMPPRoomMemoryStorage *roomMemoryStorage = [[XMPPRoomMemoryStorage alloc] init];

    XMPPJID *roomJID = [XMPPJID jidWithString:ChatRoomJID];

    xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:roomMemoryStorage jid:roomJID dispatchQueue:dispatch_get_main_queue()];

    [xmppRoom activate:xmppStream];
    [xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];

    NSXMLElement *history = [NSXMLElement elementWithName:@"history"];
    [history addAttributeWithName:@" maxchars" stringValue:@"0"];
    [xmppRoom joinRoomUsingNickname:xmppStream.myJID.user
                            history:history
                           password:nil];


    [self performSelector:@selector(ConfigureNewRoom:) withObject:nil afterDelay:4];

}

/**
 This fuction is used configure new
 */
- (void)ConfigureNewRoom:(id)sender
{
    [xmppRoom configureRoomUsingOptions:nil];
    [xmppRoom fetchConfigurationForm];
    [xmppRoom fetchBanList];
    [xmppRoom fetchMembersList];
    [xmppRoom fetchModeratorsList];

}

/**
 This fuction is called when new room is created
 */
- (void)xmppRoomDidCreate:(XMPPRoom *)sender
{
    DDLogInfo(@"%@: %@", THIS_FILE, THIS_METHOD);

    // I am inviting friends after room is created


}

/**
 This fuction is called when user joined room
 */
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
{
    [sender fetchMembersList];
    [sender fetchConfigurationForm];
    [self requestAllMesssage];
    DDLogInfo(@"%@: %@", THIS_FILE, THIS_METHOD);
    if([[self delegate] respondsToSelector:@selector(didCreatedOrJoinedRoomWithCreatedRoomName:)])
    {
        [[self delegate] didCreatedOrJoinedRoomWithCreatedRoomName:sender.myRoomJID.bare];
    }

}

- (void)xmppRoom:(XMPPRoom *)sender didFetchMembersList:(NSArray *)items
{

}

- (void)xmppRoom:(XMPPRoom *)sender occupantDidJoin:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
{
    if([[self delegate] respondsToSelector:@selector(didGetUserJoinedToRoomORLeaveRoomWithName:WithPresence:)])
    {
//        id details =occupantJID;
//        NSString* string = (NSString*)details;
         [[self delegate] didGetUserJoinedToRoomORLeaveRoomWithName:[occupantJID resource] WithPresence:[presence type]];
    }

}
- (void)xmppRoom:(XMPPRoom *)sender occupantDidLeave:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
{
    if([[self delegate] respondsToSelector:@selector(didGetUserJoinedToRoomORLeaveRoomWithName:WithPresence:)])
    {
        [[self delegate] didGetUserJoinedToRoomORLeaveRoomWithName:[occupantJID resource] WithPresence:[presence type]];
    }
}
- (void)xmppRoom:(XMPPRoom *)sender occupantDidUpdate:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
{
    if([[self delegate] respondsToSelector:@selector(didGetUserJoinedToRoomORLeaveRoomWithName:WithPresence:)])
    {
        [[self delegate] didGetUserJoinedToRoomORLeaveRoomWithName:[occupantJID resource] WithPresence:[presence type]];
    }
}


- (void) requestAllMesssage
{

//    <presence
//    from='hag66@shakespeare.lit/pda'
//    id='n13mt3l'
//    to='coven@chat.shakespeare.lit/thirdwitch'>
//    <x xmlns='http://jabber.org/protocol/muc'>
//    <history since='1970-01-01T00:00:00Z'/>
//    </x>
//    </presence>
//    
//    NSXMLElement *iQ = [NSXMLElement elementWithName:@"presence"];
//    [iQ addAttributeWithName:@"type" stringValue:@"get"];
//    [iQ addAttributeWithName:@"id" stringValue:@"n13mt3l"];
//    
//    NSXMLElement *retrieve = [NSXMLElement elementWithName:@"retrieve"];
//    [retrieve addAttributeWithName:@"xmlns" stringValue:@"urn:xmpp:archive"];
//    [retrieve addAttributeWithName:@"history since" stringValue:@"1970-01-01T00:00:00Z"];
//    
//    NSXMLElement *set = [NSXMLElement elementWithName:@"set"];
//    [set addAttributeWithName:@"xmlns" stringValue:@"http://jabber.org/protocol/muc"];
//    
//    [retrieve addChild:set];
//    [iQ addChild:retrieve];
//    
//    [xmppStream sendElement:iQ];




}

- (void)xmppRoom:(XMPPRoom *)sender didFetchConfigurationForm:(NSXMLElement *)configForm
{
    DDLogInfo(@"%@: %@", THIS_FILE, THIS_METHOD);

    NSXMLElement *newConfig = [configForm copy];
    NSArray *fields = [newConfig elementsForName:@"field"];

    for (NSXMLElement *field in fields)
    {
        NSString *var = [field attributeStringValueForName:@"var"];

        // Make Room Persistent
        if ([var isEqualToString:@"muc#roomconfig_persistentroom"])
        {

            [field removeChildAtIndex:0];
            [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]];
        }

        if ([var isEqualToString:@"roomconfig_enablelogging"])
        {

            [field removeChildAtIndex:0];
            [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]];
        }

        if ([var isEqualToString:@"muc#roomconfig_maxusers"])
        {

            [field removeChildAtIndex:0];
            [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"100"]];
        }


    }
    //    [sender configureRoomUsingOptions:newConfig];
}

/**
 This fuction is used to destroy created room
 */
- (void) destroyCreatedRoom
{
    [xmppRoom destroyRoom];

}


- (BOOL)sendGroupMessageWithBody:(NSString*)_body
{

    [xmppRoom sendMessageWithBody:_body];
    return YES;
}


@end
#导入“MessageManager.h”
#导入“DDLog.h”
#导入“DDTTYLogger.h”
#进口
#如果调试
静态常量int ddLogLevel=LOG\u LEVEL\u VERBOSE;
#否则
静态常量int ddLogLevel=日志级别信息;
#恩迪夫
@接口消息管理器()
@结束
静态MessageManager*sharedMessageHandler=nil;
@实现消息管理器
@syn