IOS:无法使用 XMPP 框架验证我的 JabberID
Posted
技术标签:
【中文标题】IOS:无法使用 XMPP 框架验证我的 JabberID【英文标题】:IOS: Can't authenticate my JabberID with XMPP Framework 【发布时间】:2014-04-21 17:37:42 【问题描述】:我刚刚在此处 (http://code.tutsplus.com/tutorials/building-a-jabber-client-for-ios-xmpp-setup--mobile-7190) 学习了本教程,但我很难让应用正常运行。
我正在使用 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
我找不到任何资源来为我指明正确的方向,有什么想法吗?
-- 更新
这是执行此代码的类:
@interface JabberClientAppDelegate : NSObject <UIApplicationDelegate>
UIWindow *window;
JabberClientViewController *viewController;
XMPPStream *xmppStream;
NSString *password;
BOOL isOpen;
__weak NSObject *_chatDelegate;
__weak NSObject *_messageDelegate;
【问题讨论】:
您的应用委托中有该代码吗?它有一个名为 xmppStream 的属性吗?可能将[self xmppStream]
切换到sender
可以让您继续,但稍后您会遇到问题。让我知道那是哪个类以及它是否具有 xmppStream 属性,然后我可以为您提供更多帮助
是的,它是应用委托类。我决定“重置模拟器的内容和设置”,现在不再调用此方法......仍然无法从我的本地 XMPP 服务器中看到联系人列表。您是否有一个 STTCPW 项目清楚地说明诸如连接、检索用户、向特定用户发送消息等操作?
很遗憾,我无法在互联网上分享任何内容。要获取联系人列表,您应该使用 Roster 扩展,它会在连接流后请求联系人列表:XMPPRosterCoreDataStorage *xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] initWithInMemoryStore]; XMPPRoster *xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage]; xmppRoster.autoFetchRoster = YES; [xmppRoster activate:_xmppStream];
酷!是的,我注意到博主的代码正在使用名册,框架中的示例也在使用它(github.com/robbiehanson/XMPPFramework/tree/master/Xcode/…)——我能够运行示例应用程序并加载联系人,所以我想我应该尝试检查差异并从那里获取...谢谢@Matias_R!
【参考方案1】:
您的问题可能是 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
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
【讨论】:
以上是关于IOS:无法使用 XMPP 框架验证我的 JabberID的主要内容,如果未能解决你的问题,请参考以下文章