我正在尝试使用以下代码行向用户的名单添加新伙伴:
XMPPJID jid = [XMPPJID jidWithString:[NSString stringWithFormat:@"%@@localhost",addBuddyTextField.text]]; [appDelegate.xmppRoster addUser:jid withNickname:addBuddyTextField.text];
这有效.其他用户收到订阅请求通知,他可以接受它,一切正常.新好友将被添加到XMPPRosterMemoryStorage中,并将显示在[XMPPRosterMemoryStorage unsortedUsers] NSArray上,以便可以在UI上显示当前名单及其所有好友.
但是一旦用户退出并重新启动应用程序,整个名单就会消失,他添加了所有的好友. [XMPPRoster fetchRoster]和以下方法[XMPPRosterMemoryStorage unsortedUsers]返回一个没有项目的NSArray.
我是否必须将好友更新(添加,删除)发布到XMPPServer?或者我的XMPPserver(ejabberd)不支持名册?
这是我用来激活XMPPRoster的代码:
xmppRosterMemStorage = [[XMPPRosterMemoryStorage alloc] init]; xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterMemStorage dispatchQueue:dispatch_get_main_queue()]; [xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()]; xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = false; xmppRoster.autoFetchRoster = true; [xmppRoster activate:xmppStream]; [xmppRoster fetchRoster];
解决方法
从上面的讨论来看,听起来你的服务器正好收到您的名册请求.使用您的设置代码我无法重现您遇到的问题.
您可以尝试打开日志记录并查看是否阅读协议日志可以帮助您了解发生的情况:
#import "DDTTYLogger.h" - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { [DDLog addLogger:[DDTTYLogger sharedInstance]]; ...
或者尝试使用您的服务器测试代码,如果问题消失,请从那里开始工作:
#import "AppDelegate.h" #import "XMPPFramework.h" #import "DDTTYLogger.h" #import "DDLog.h" static const int ddLogLevel = LOG_LEVEL_VERBOSE; NSString * const XMPPAuthenticationMethodPlain = @"Plain"; NSString * const XMPPAuthenticationMethodDigestMD5 = @"Digest-MD5"; NSString * const OptionHostName = @"..."; NSUInteger const OptionPort = 5222; BOOL const OptionOldSchoolSSL = NO; NSString * const OptionJID = @"..."; NSString * const OptionAuthenticationMethod = @"Digest-MD5"; NSString * const OptionPassword = @"..."; @interface AppDelegate () <XMPPStreamDelegate,XMPPRosterMemoryStorageDelegate> @property (retain) XMPPStream *xmppStream; @property (retain) XMPPRosterMemoryStorage *xmppRosterMemStorage; @property (retain) XMPPRoster *xmppRoster; @end @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { [DDLog addLogger:[DDTTYLogger sharedInstance]]; self.xmppStream = [[XMPPStream alloc] init]; [self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()]; self.xmppStream.hostName = OptionHostName; self.xmppStream.hostPort = OptionPort; self.xmppStream.myJID = [XMPPJID jidWithString:OptionJID]; self.xmppRosterMemStorage = [[XMPPRosterMemoryStorage alloc] init]; self.xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:self.xmppRosterMemStorage dispatchQueue:dispatch_get_main_queue()]; [self.xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()]; [self.xmppRoster activate:self.xmppStream]; NSError *error = nil; if (OptionOldSchoolSSL) [self.xmppStream oldSchoolSecureConnect:&error]; else [self.xmppStream connect:&error]; } -(void)applicationWillTerminate:(NSNotification *)notification { [self.xmppStream removeDelegate:self]; [self.xmppStream disconnect]; } -(void)xmppStreamDidConnect:(XMPPStream *)sender { Class authClass = nil; if ([OptionAuthenticationMethod isEqual:XMPPAuthenticationMethodPlain]) authClass = [XMPPPlainAuthentication class]; else if ([OptionAuthenticationMethod isEqual:XMPPAuthenticationMethodDigestMD5]) authClass = [XMPPDigestMD5Authentication class]; else { DDLogWarn(@"Unrecognized auhthentication method '%@',falling back on Plain",OptionAuthenticationMethod); authClass = [XMPPPlainAuthentication class]; } id<XMPPSASLAuthentication> auth = [[authClass alloc] initWithStream:sender password:OptionPassword]; NSError *error = nil; if (![sender authenticate:auth error:&error]) NSLog(@"Error authenticating: %@",error); } -(void)xmppRosterDidPopulate:(XMPPRosterMemoryStorage *)sender { NSLog(@"users: %@",[sender unsortedUsers]); // My subscribed users do print out } @end
如果我将名单设置代码移动到-xmppStreamDidAuthenticate,它也可以工作,但在这种情况下我需要手动调用-fetchRoster.