Функции делегата XMPPFramework вызываются в симуляторе, но не на телефоне

Я следую руководству по адресу: http://mobile.tutsplus.com/tutorials/iphone/building-a-jabber-client-for-ios-server-setup/, чтобы настроить приложение iOS с сервером ejabberd. Пока что я практически скопировал код в новый проект.

Моя проблема в том, что функции делегата XMPP AppDelegate.m не вызываются при запуске на телефоне. В Симуляторе все работает нормально, и вызываются две функции, указанные ниже.

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

}

Я могу подключиться как к телефону, так и к симулятору, поскольку этот вызов выполняется без ошибок:

[xmppStream connect:&error]

Вот мой код AppDelegate.h:

#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

И 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

person OdieO    schedule 06.03.2013    source источник


Ответы (2)


Если вы посмотрите на свой setupStream метод, вы используете имя «localhost». Это наводит меня на мысль, что сервер находится на вашей машине разработки, и устройство пытается подключиться к самому себе (localhost). Вам нужно будет заменить это на имя вашего сервера.

Это, вероятно, работает в симуляторе, потому что клиент и сервер - одно и то же.

ОБНОВЛЕНИЕ:

Я только что прочитал руководство, и оно совсем не помогает описать, как оно будет работать на реальном устройстве.

person Mike D    schedule 07.03.2013
comment
Большое спасибо. Я был частично сбит с толку, потому что вызывается [xmppStream connect: & error] без возврата ошибки, и я думал, что первоначальное соединение было выполнено, но где-то после этого возникали ошибки. - person OdieO; 07.03.2013

как сказал Майк Д., вы подключаетесь к серверу, который находится на вашем компьютере ([xmppStream setHostName: @ "localhost"];) Чтобы подключиться к "localhost", вам необходимо изменить файл hosts на вашем устройстве (/ etc / hosts), но это запрещено Apple, поскольку ваше приложение не может изменять данные за пределами песочницы (если устройство не взломано). Я делал это на телефоне Android, когда сталкивался с подобной проблемой в прошлом. Проверьте это обсуждение (Существует ли файл hosts на iPhone? Как его поменять?)

person macL0vin    schedule 14.10.2014