2013-03-11 17 views
7

Zacząłem od xmppframework ostatnio, ale utknąłem z problemem. Mogę połączyć się z moim serwerem w mojej sieci lokalnej, ale metody xmppstreamdelegate nie są wywoływane w moim niestandardowym klasy, ale działa absolutnie dobrze na klasy appdelegate. Czy ktoś może mi w tym pomóc. Czy delegat jest obsługiwany tylko w klasie appdelegate?Metody delegatów xmppstream nie są wywoływane w mojej klasie niestandardowej

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 

Realizacja:

@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 
+0

Czy mógłbyś podać wcięcie swojego kodu? – paulmelnikow

+0

@noa będę wcięć. –

+0

Czy '-setupStream' wywołał instancję XmppClass? I '-connect'? Czy '[połączenie xmppStream]' zwraca TAK? Czy używasz ARC? Jakie są wyniki? Jaki jest kod, który tworzy twoją instancję XmppClass? – paulmelnikow

Odpowiedz

1

Najprawdopodobniej problemem jest to, czy instancja klasy, który jest delegatem do XMPPStream zostanie zwolniony przed Metoda delegatów jest na nią wywoływana. Uczyń ją bardziej trwałą, nadając tej klasie właściwość lub instancję zmiennej innej klasy lub używając parametru dispatch_once. Na przykład,

Zmień

YourClass *instance = [[YourClass alloc] init]; 
instance.xmppStream = .... 

przez

@property(nonatomic, strong) YourClass *instance; 
self.instance = [[YourClass alloc] init]; 
self.instance.xmppStream = .... 

Tutaj YourClass zawiera XMPPStream i przekazać do niego.

Napisałem duży post na blogu dotyczący tego problemu. Jest to dość powszechna sytuacja. http://blog.alwawee.com/2013/07/31/on-xmppframework-delegate-method-not-being-called/

+0

Mam ten sam problem. Twój wpis na blogu zaginął, czy mogę go znaleźć gdzie indziej? Dzięki! – user2011985

+1

http://blog.alwawee.com/2013/07/31/on-xmppframework-delegate-method-not-being-called/ - tutaj jest – wzbozon

+0

Fajnie, dzięki! :) – user2011985

0

można użyć multicast sth jak ten

[[self appDelegate].xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()]; 
0

miałem ten sam problem ... pomógł mi. Mam nadzieję, że to działa dla Ciebie, po prostu wykonaj następujące zmiany w swoim kodzie.

Static XmppClass *selfRef = nil; 
@implementation XmppClass 
@synthesize xmppStream; 
- (void)setupStream 
{ 
// Setup xmpp stream 
selfRef = [[XmppClass alloc] init]; 
xmppStream = [[XMPPStream alloc] init]; 
[xmppStream addDelegate:selfRef delegateQueue:dispatch_get_main_queue()]; 
Powiązane problemy