I started with xmppframework recently,but i am stuck with an issue.i am able to connect to my server on my local network but the xmppstreamdelegate methods are not getting called on my custom class,but works absolutely fine on appdelegate class .Can anyone pls help me on this.Is the delegate only supported on the appdelegate class ?
Header:
@interface XmppClass : NSObject<XMPPStreamDelegate>{
XMPPStream *xmppStream;
Login * loginDetail;
BOOL allowSelfSignedCertificates;
BOOL allowSSLHostNameMismatch;
}
@property (nonatomic, strong, readonly) XMPPStream *xmppStream;
@property (nonatomic, strong) Login *loginDetail;
- (id)initWithLogin:(Login *) loginrefernce;
- (BOOL)connect;
- (void)disconnect;
- (void)setupStream;
@end
Implementation:
@implementation XmppClass
@synthesize xmppStream;
@synthesize loginDetail;
- (id)initWithLogin:(Login *) loginrefernce
{
self = [super init];
if (self) {
self.loginDetail=loginrefernce;
[DDLog addLogger:[DDTTYLogger sharedInstance]];
[self setupStream];
[self connect];
}
return self;
}
- (void)setupStream
{
NSAssert(xmppStream == nil, @"Method setupStream invoked multiple times");
// 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];
#if !TARGET_IPHONE_SIMULATOR
{
// Want xmpp to run in the background?
//
// P.S. - The simulator doesn't support backgrounding yet.
// When you try to set the associated property on the simulator, it simply fails.
// And when you background an app on the simulator,
// it just queues network traffic til the app is foregrounded again.
// We are patiently waiting for a fix from Apple.
// If you do enableBackgroundingOnSocket on the simulator,
// you will simply see an error message from the xmpp stack when it fails to set the property.
xmppStream.enableBackgroundingOnSocket = YES;
}
#endif
NSLog(@"setup stream");
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
[xmppStream setHostName:@"10.68.202.123"];
//[xmppStream setHostPort:8070];
allowSelfSignedCertificates = NO;
allowSSLHostNameMismatch = NO;
// You may need to alter these settings depending on the server you're connecting to
}
- (BOOL)connect
{
NSLog(@"connect");
if (![xmppStream isDisconnected]) {
return YES;
}
//
// If you don't want to use the Settings view to set the JID,
// uncomment the section below to hard code a JID and password.
//
// myJID = @"[email protected]/xmppframework";
// myPassword = @"";
if (self.loginDetail.emailId == nil || self.loginDetail.password == nil) {
return NO;
}
[xmppStream setMyJID:[XMPPJID jidWithString:[self.loginDetail.emailId stringByAppendingString:@"/pc"]]];
NSError *error = nil;
if (![xmppStream connect:&error])
{
NSLog(@"Error connecting: %@", error);
return NO;
}
return YES;
}
- (void)disconnect
{
[xmppStream disconnect];
}
- (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:(NSMutableDictionary *)settings
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
NSLog(@"some security thing");
if (allowSelfSignedCertificates)
{
[settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsAnyRoot];
}
if (allowSSLHostNameMismatch)
{
[settings setObject:[NSNull null] forKey:(NSString *)kCFStreamSSLPeerName];
}
else
{
// Google does things incorrectly (does not conform to RFC).
// Because so many people ask questions about this (assume xmpp framework is broken),
// I've explicitly added code that shows how other xmpp clients "do the right thing"
// when connecting to a google server (gmail, or google apps for domains).
NSString *expectedCertName = nil;
NSString *serverDomain = xmppStream.hostName;
NSString *virtualDomain = [xmppStream.myJID domain];
if ([serverDomain isEqualToString:@"talk.google.com"])
{
if ([virtualDomain isEqualToString:@"gmail.com"])
{
expectedCertName = virtualDomain;
}
else
{
expectedCertName = serverDomain;
}
}
else if (serverDomain == nil)
{
expectedCertName = virtualDomain;
}
else
{
expectedCertName = serverDomain;
}
if (expectedCertName)
{
[settings setObject:expectedCertName forKey:(NSString *)kCFStreamSSLPeerName];
}
}
}
- (void)xmppStreamDidSecure:(XMPPStream *)sender
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
NSLog(@"connected");
NSError *error = nil;
if (![[self xmppStream] authenticateWithPassword:self.loginDetail.password error:&error])
{
DDLogError(@"Error authenticating: %@", error);
}
}
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
NSLog(@"authenticated");
}
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
NSLog(@"did not authenticate");
}
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
return NO;
}
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
// A simple example of inbound message handling.
}
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [presence fromStr]);
}
- (void)xmppStream:(XMPPStream *)sender didReceiveError:(id)error
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
NSLog(@"%@",error);
}
@end
Most probably the problem is that your class instance, that is a delegate for your XMPPStream is released before the delegate method is called on it. Make it more persistent by making this class a property or instance variable of other class or by using dispatch_once. For example,
Change
YourClass *instance = [[YourClass alloc] init];
instance.xmppStream = ....
by
@property(nonatomic, strong) YourClass *instance;
self.instance = [[YourClass alloc] init];
self.instance.xmppStream = ....
Here YourClass contains XMPPStream and is delegate for it.
I've written a big blog post on this problem. This is pretty common situation. http://blog.alwawee.com/2013/07/31/on-xmppframework-delegate-method-not-being-called/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With