3

I'm following the tutorial at: http://mobile.tutsplus.com/tutorials/iphone/building-a-jabber-client-for-ios-server-setup/ to set up an iOS app with an ejabberd server. So far I have pretty much copied the code over to a new project.

My problem is that the XMPP delegate functions AppDelegate.m are not being called when run on the phone. Everything works fine in Simulator and the two functions below are called.

  - (void)xmppStreamDidConnect:(XMPPStream *)sender {
    NSLog(@"in WSAppDelegate - xmppStreamDidConnect");
    isOpen = YES;
    NSError *error = nil;
    [[self xmppStream] authenticateWithPassword:password error:&error];

}

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
    NSLog(@"in WSAppDelegate - xmppStreamDidAuthenticate");

    [self goOnline];

}

I am able to connect on both the phone and simulator as this call runs without error:

[xmppStream connect:&error]

Here is my AppDelegate.h code:

#import <UIKit/UIKit.h>
#import "XMPPRoster.h"
#import "XMPP.h"
#import "SMChatDelegate.h"
#import "SMMessageDelegate.h"

@class SMBuddyListViewController;

@interface WSAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    SMBuddyListViewController *viewController;

    XMPPStream *xmppStream;
    XMPPRoster *xmppRoster;

    NSString *password;

    BOOL isOpen;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet SMBuddyListViewController *viewController;


@property (nonatomic, readonly) XMPPStream *xmppStream;
@property (nonatomic, readonly) XMPPRoster *xmppRoster;

@property (nonatomic, assign) id  _chatDelegate;
@property (nonatomic, assign) id  _messageDelegate;

- (BOOL)connect;
- (void)disconnect;

@end

And AppDelegate.m:

#import "WSBuddyListViewController.h"


@interface WSAppDelegate()

- (void)setupStream;

- (void)goOnline;
- (void)goOffline;

@end


@implementation WSAppDelegate

@synthesize xmppStream;
@synthesize xmppRoster;
@synthesize window;
@synthesize viewController;
@synthesize _chatDelegate;
@synthesize _messageDelegate;


- (void)applicationWillResignActive:(UIApplication *)application {

    [self disconnect];

}

- (void)applicationDidBecomeActive:(UIApplication *)application {

    [self setupStream];
    BOOL connected = NO;
    connected = [self connect];
    NSLog(@"*** connected = %i", connected);


}

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

    return YES;
}


- (void)setupStream {
    NSLog(@"in WSAppDelegate - setupStream");

    xmppStream = [[XMPPStream alloc] init];
    [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
    [xmppStream setHostName:@"localhost"];

}

- (void)goOnline {
    NSLog(@"in WSAppDelegate - goOnline");

    XMPPPresence *presence = [XMPPPresence presence];
    [[self xmppStream] sendElement:presence];
}

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

- (BOOL)connect {
    NSLog(@"in WSAppDelegate - connect");

    [self setupStream];

    NSString *jabberID = [[NSUserDefaults standardUserDefaults] stringForKey:@"userID"];
    NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:@"userPassword"];

    if (![xmppStream isDisconnected]) {
        NSLog(@"in WSAppDelegate - connect - if (![xmppStream isDisconnected]) ");

        return YES;
    }


    if (jabberID == nil || myPassword == nil) {
        NSLog(@"in WSAppDelegate - connect - if (jabberID == nil || myPassword == nil)");

        return NO;
    }

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

    NSError *error = nil;
    if (![xmppStream connect:&error])
    {
        NSLog(@"in WSAppDelegate - connect - if (![xmppStream connect:&error]))");

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error"
                                                            message:[NSString stringWithFormat:@"Can't connect to server %@", [error localizedDescription]]
                                                           delegate:nil
                                                  cancelButtonTitle:@"Ok"
                                                  otherButtonTitles:nil];
        [alertView show];


        return NO;
    }

    return YES;
}

- (void)disconnect {

    [self goOffline];
    [xmppStream disconnect];
    [_chatDelegate didDisconnect];
}



#pragma mark -
#pragma mark XMPP delegates


- (void)xmppStreamDidConnect:(XMPPStream *)sender {
    NSLog(@"in WSAppDelegate - xmppStreamDidConnect");
    isOpen = YES;
    NSError *error = nil;
    [[self xmppStream] authenticateWithPassword:password error:&error];

}

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
    NSLog(@"in WSAppDelegate - xmppStreamDidAuthenticate");

    [self goOnline];

}


- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq {

    return NO;

}

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message {
    NSLog(@"in WSAppDelegate - xmppStream:(XMPPStream *)sender didReceiveMessage");


    NSString *msg = [[message elementForName:@"body"] stringValue];
    NSString *from = [[message attributeForName:@"from"] stringValue];

    NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
    [m setObject:msg forKey:@"msg"];
    [m setObject:from forKey:@"sender"];

    [_messageDelegate newMessageReceived:m];

}

- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence {
    NSLog(@"in WSAppDelegate - xmppStream:(XMPPStream *)sender didReceivePresence:");

    NSString *presenceType = [presence type]; // online/offline
    NSString *myUsername = [[sender myJID] user];
    NSString *presenceFromUser = [[presence from] user];

    if (![presenceFromUser isEqualToString:myUsername]) {

        if ([presenceType isEqualToString:@"available"]) {

            [_chatDelegate newBuddyOnline:[NSString stringWithFormat:@"%@@%@", presenceFromUser, @"localhost"]];

        } else if ([presenceType isEqualToString:@"unavailable"]) {

            [_chatDelegate buddyWentOffline:[NSString stringWithFormat:@"%@@%@", presenceFromUser, @"localhost"]];

        }

    }

}


- (void)dealloc {

    [xmppStream removeDelegate:self];
    [xmppRoster removeDelegate:self];

    [xmppStream disconnect];
}
@end
OdieO
  • 6,836
  • 7
  • 56
  • 88

2 Answers2

8

If you look at your setupStream method, you are using the name "localhost." This is leading me to believe the server is on your development machine, and the device is trying to connect to itself (localhost). You will have to replace that with your server name.

This likely works in the simulator because the the client and server are one and the same.

UPDATE:

I just read through the tutorial, and it does not do a good job at all at describing how it would work on real device.

Mike D
  • 4,938
  • 6
  • 43
  • 99
  • Thanks so much. I was thrown off partially because [xmppStream connect:&error] is called without returning an error, and I thought an initial connected was made but errors were occurring somewhere after that. – OdieO Mar 07 '13 at 03:49
0

as Mike D said, you're connecting to the server which is on your machine([xmppStream setHostName:@"localhost"];) In order to connect to the "localhost" you have to change hosts file on your device(/etc/hosts), but that is forbidden by Apple, since your app cant change stuff outside the sandbox.(unless the device is jailbroken). I've done this stuff on an android phone, when faced similar problem in the past. Check this discussion(Does hosts file exist on the iPhone? How to change it?)

Community
  • 1
  • 1
macL0vin
  • 183
  • 2
  • 11