ios - XMPPRoster 不会将新好友发布到 XMPP 服务器

标签 ios xmpp xmppframework

我正在尝试使用这行代码将新好友添加到用户名册中:

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 吗?还是我的 XMPP 服务器 (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];

最佳答案

从上面的讨论来看,听起来您的服务器可以很好地处理您的花名册请求。使用您的设置代码我无法重现您遇到的问题。

您可以尝试打开日志记录,看看阅读协议(protocol)日志是否有助于您了解正在发生的事情:

#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

关于ios - XMPPRoster 不会将新好友发布到 XMPP 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14647329/

相关文章:

ios - XMPP连接将错误连接超时

ios - 如何在应用程序处于终止状态时在 iOS 设备中接收消息以及如何在打开 wifi/移动数据时提醒应用程序

ios - 在 sprite kit Xcode 中创建一个整数数组

ios - Azure 移动服务自定义 API 多次调用 SQL SP

ios - XMPP 客户端网络故障和 Openfire 离线消息

ios - XMPPFramework - 群聊实现

ios - XMPPFramework-无法连接到Openfire服务器

ios - 在 iOS 的 xmppframework 中使用 XMPPAutoTime 的正确方法是什么

iOS 自定义键盘类型

ios - 发布使用旧版 SDK 构建的 iOS 应用程序