ios - XMPPFramework - 消息未发送

标签 ios xmpp xmppframework

我是 iOS 的新手。我正在使用 XMPPFramework 构建应用程序。但是最近几天我遇到了一个问题。找不到任何解决方案。问题是当我想向任何特定的 id 发送消息时,消息没有被发送。发送消息的 Action 方法是:

- (IBAction)sendMsg:(id)sender 
{
    xmppStream = [[XMPPStream alloc] init];
    [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];

    NSString *messageStr = self.msgField.text;

    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:@"abc.codemen@gmail.com"];
        [message addChild:body];    
        [self.xmppStream sendElement:message];
    }
}

这是在我的 XMPPStream.m 中发送 NSXMLElement 的 sendElement 方法:

- (void)sendElement:(NSXMLElement *)element
{
    if (element == nil)
        return;

    dispatch_block_t block = ^{ @autoreleasepool {
        if (state == STATE_XMPP_CONNECTED)
            [self sendElement:element withTag:TAG_XMPP_WRITE_STREAM];
    }};

    if (dispatch_get_current_queue() == xmppQueue)
            block();
    else
            dispatch_async(xmppQueue, block);
}

但是我发现消息发送的方法调用没有进入if语句!

if (state == STATE_XMPP_CONNECTED)
{
    [self sendElement:element withTag:TAG_XMPP_WRITE_STREAM];
}

我想这就是我无法向任何 id 发送消息的原因。请帮助我提出错误或正确的建议,以及如何解决问题?

这是我的 Appdelegate 类:

#import "iPhoneXMPPAppDelegate.h"
#import "GCDAsyncSocket.h"
#import "XMPP.h"
#import "XMPPReconnect.h"
#import "XMPPCapabilitiesCoreDataStorage.h"
#import "XMPPRosterCoreDataStorage.h"
#import "XMPPvCardAvatarModule.h"
#import "XMPPvCardCoreDataStorage.h"
#import "DDLog.h"
#import "DDTTYLogger.h"
#import <CFNetwork/CFNetwork.h>
#import "ParentLoginViewController.h"
#import "Child.h"

// Log levels: off, error, warn, info, verbose
#if DEBUG
static const int ddLogLevel = LOG_LEVEL_VERBOSE;
#else
static const int ddLogLevel = LOG_LEVEL_INFO;
#endif

@implementation iPhoneXMPPAppDelegate

//@synthesize window = _window;
@synthesize managedObjectContext = __managedObjectContext;
@synthesize managedObjectModel = __managedObjectModel;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
@synthesize xmppStream;
@synthesize xmppReconnect;
@synthesize xmppRoster;
@synthesize xmppRosterStorage;
@synthesize xmppvCardTempModule;
@synthesize xmppvCardAvatarModule;
@synthesize xmppCapabilities;
@synthesize xmppCapabilitiesStorage;
@synthesize window;
@synthesize navigationController;

static iPhoneXMPPAppDelegate *sharedInstance = nil;

// Get the shared instance and create it if necessary.
+ (iPhoneXMPPAppDelegate *)sharedInstance {
if (sharedInstance == nil) {
    sharedInstance = [[super allocWithZone:NULL] init];
}

return sharedInstance;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

[DDLog addLogger:[DDTTYLogger sharedInstance]];

[self setupStream];

if (![self connect])
{
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.0 *       NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

            ParentLoginViewController *parent = [[ParentLoginViewController alloc] initWithNibName:@"ParentLoginViewController" bundle:nil];
            [navigationController presentModalViewController:parent  animated:YES];
        });
    }

    return YES;
}

- (void)dealloc
{
[self teardownStream];
}

- (NSManagedObjectContext *)managedObjectContext_roster
{
    return [xmppRosterStorage mainThreadManagedObjectContext];
}

- (NSManagedObjectContext *)managedObjectContext_capabilities
{
    return [xmppCapabilitiesStorage mainThreadManagedObjectContext];
}

- (void)setupStream
{
    NSAssert(xmppStream == nil, @"Method setupStream invoked multiple times");

    xmppStream = [[XMPPStream alloc] init];

    #if !TARGET_IPHONE_SIMULATOR
    {
        xmppStream.enableBackgroundingOnSocket = YES;
    }
    #endif

    xmppReconnect = [[XMPPReconnect alloc] init];

    xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];

    xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];

    xmppRoster.autoFetchRoster = YES;
    xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;

    xmppvCardStorage = [XMPPvCardCoreDataStorage sharedInstance];
    xmppvCardTempModule = [[XMPPvCardTempModule alloc]   initWithvCardStorage:xmppvCardStorage];

    xmppvCardAvatarModule = [[XMPPvCardAvatarModule alloc] initWithvCardTempModule:xmppvCardTempModule];

    xmppCapabilitiesStorage = [XMPPCapabilitiesCoreDataStorage sharedInstance];
    xmppCapabilities = [[XMPPCapabilities alloc] initWithCapabilitiesStorage:xmppCapabilitiesStorage];

    xmppCapabilities.autoFetchHashedCapabilities = YES;
    xmppCapabilities.autoFetchNonHashedCapabilities = NO;

    // Activate XMPP modules

    [xmppReconnect         activate:xmppStream];
    [xmppRoster            activate:xmppStream];
    [xmppvCardTempModule   activate:xmppStream];
    [xmppvCardAvatarModule activate:xmppStream];
    [xmppCapabilities      activate:xmppStream];

    // Add ourself as a delegate to anything we may be interested in

    [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
    [xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];
    [xmppStream setHostName:@"talk.google.com"];
    [xmppStream setHostPort:5222];

    // You may need to alter these settings depending on the server you're connecting to
    allowSelfSignedCertificates = NO;
    allowSSLHostNameMismatch = NO;
}

- (void)teardownStream
{
    [xmppStream removeDelegate:self];
    [xmppRoster removeDelegate:self];

    [xmppReconnect         deactivate];
    [xmppRoster            deactivate];
    [xmppvCardTempModule   deactivate];
    [xmppvCardAvatarModule deactivate];
    [xmppCapabilities      deactivate];

    [xmppStream disconnect];

    xmppStream = nil;
    xmppReconnect = nil;
    xmppRoster = nil;
    xmppRosterStorage = nil;
    xmppvCardStorage = nil;
    xmppvCardTempModule = nil;
    xmppvCardAvatarModule = nil;
    xmppCapabilities = nil;
    xmppCapabilitiesStorage = nil;
}

- (void)goOnline
{
    XMPPPresence *presence = [XMPPPresence presence]; // type="available" is implicit

    [[self xmppStream] sendElement:presence];
}

- (void)goOffline
{
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];

    [[self xmppStream] sendElement:presence];
}


- (BOOL)connect
{
    if (![xmppStream isDisconnected]) {
        return YES;
    }

    NSString *myJID = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyJID];
    NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyPassword];

    if (myJID == nil || myPassword == nil) {
        return NO;
    }

    [xmppStream setMyJID:[XMPPJID jidWithString:myJID]];
    password = myPassword;

    NSError *error = nil;
    if (![xmppStream connect:&error])
    {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error connecting" 
                                                        message:@"See console for error details." 
                                                       delegate:nil 
                                              cancelButtonTitle:@"Ok" 
                                              otherButtonTitles:nil];
        [alertView show];

        DDLogError(@"Error connecting: %@", error);

        return NO;
    }

    return YES;
}

- (void)disconnect
{
    [self goOffline];
    [xmppStream disconnect];
}

- (void)applicationWillEnterForeground:(UIApplication *)application 
{
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}


- (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket 
{
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}

- (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:(NSMutableDictionary  *)settings
{
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);

    if (allowSelfSignedCertificates)
    {
        [settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString  *)kCFStreamSSLAllowsAnyRoot];
    }

    if (allowSSLHostNameMismatch)
    {
        [settings setObject:[NSNull null] forKey:(NSString *)kCFStreamSSLPeerName];
    }

    else
    {
        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);

    isXmppConnected = YES;

    NSError *error = nil;

    if (![[self xmppStream] authenticateWithPassword:password error:&error])
    {
        DDLogError(@"Error authenticating: %@", error);
    }
}

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);

    [self goOnline];
}

- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}

- (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.

    if ([message isChatMessageWithBody])
    {
        NSLog(@"Message is: %@",message); 

        XMPPUserCoreDataStorageObject *user = [xmppRosterStorage userForJID:[message      from]                                                                  xmppStream:xmppStream managedObjectContext:[self managedObjectContext_roster]];

        NSString *body = [[message elementForName:@"body"] stringValue];
        NSString *displayName = [user displayName];

        if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
        {
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:displayName
                                                          message:body 
                                                         delegate:nil 
                                                cancelButtonTitle:@"Ok" 
                                                otherButtonTitles:nil];
            [alertView show];
        }
        else
        {
            // We are not active, so use a local notification instead
            UILocalNotification *localNotification = [[UILocalNotification alloc] init];
            localNotification.alertAction = @"Ok";
            localNotification.alertBody = [NSString stringWithFormat:@"From: %@\n\n%@",displayName,body];

            [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
        }
    }
}

- (void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message
{  
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}

- (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);

    if (!isXmppConnected)
    {
        DDLogError(@"Unable to connect to server. Check xmppStream.hostName");
    }
}

#pragma mark XMPPRosterDelegate

- (void)xmppRoster:(XMPPRoster *)sender didReceiveBuddyRequest:(XMPPPresence *)presence
{
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);

    XMPPUserCoreDataStorageObject *user = [xmppRosterStorage userForJID:[presence from]
                                                         xmppStream:xmppStream
                                               managedObjectContext:[self managedObjectContext_roster]];

    NSString *displayName = [user displayName];
    NSString *jidStrBare = [presence fromStr];
    NSString *body = nil;

    if (![displayName isEqualToString:jidStrBare])
    {
        body = [NSString stringWithFormat:@"Buddy request from %@ <%@>", displayName, jidStrBare];
    }
    else
    {
        body = [NSString stringWithFormat:@"Buddy request from %@", displayName];
    }


    if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
    {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:displayName
                                                        message:body 
                                                       delegate:nil 
                                              cancelButtonTitle:@"Not implemented"
                                              otherButtonTitles:nil];
        [alertView show];
    } 
    else 
    {
        // We are not active, so use a local notification instead
        UILocalNotification *localNotification = [[UILocalNotification alloc] init];
        localNotification.alertAction = @"Not implemented";
        localNotification.alertBody = body;

        [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
    }
}

-(void)sendingMessage
{       
    NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
    [body setStringValue:@"Hello brother"];

    NSXMLElement *message = [NSXMLElement elementWithName:@"message"];
    [message addAttributeWithName:@"type" stringValue:@"chat"];
    [message addAttributeWithName:@"to" stringValue:@"abc.codemen@gmail.com"];
    [message addChild:body];

    [self.xmppStream sendElement:message];

    NSLog(@"message sending! : %@",message);
}

@end

最佳答案

如果您是 xmpp 框架的新手,那么您应该首先为聊天客户端设置服务器(如 Ejabbered、openfire),然后您必须为聊天配置它。您将从以下链接中找到非常好的教程,该链接分为四个部分。请逐步查看本教程:-

http://mobile.tutsplus.com/tutorials/iphone/building-a-jabber-client-for-ios-server-setup/

关于ios - XMPPFramework - 消息未发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16013558/

相关文章:

ios - 在没有segue的情况下在两个 View Controller 之间传递数据?

iphone - 服务器无法识别 iPhone 中 HTTP header SOAPAction 的值?

Google Analytics 集成后 iOS 应用程序崩溃

php - 与 Jabber/Aim 集成的简单 web "live chat"软件(LAMP 堆栈)

ios - XMPPFramework 没有日志输出,通过 cocoapods 安装

ios - 使用 UIPresentationController 和 Tab 栏向上滑动菜单

node.js - Nodejs XMPP 组件使用

android - 如何将自定义扩展名(时间)添加到 <message> 标签?

swift - xmppStreamDidConnect 未在 "swift framework"中调用

ios - 与明火服务器的 XMPPFramework SSL 连接未连接