Нужна помощь: моя программа должна реагировать, когда другой класс делает что-то конкретное - не так просто, как кажется - PullRequest
0 голосов
/ 06 января 2010

Я пишу программу, которая использует твиттер. Я хочу, чтобы мое приложение отображало UIAlertView, когда пользователь нажимает кнопку «Tweet» и имя пользователя или пароль неверны. Для своей функции Twitter я использую TwitterRequest.m / h от Брэндона Требитовски. Если все работает отлично и имя пользователя / пароль верны, это происходит в моем приложении:

        TwitterRequest * t = [[TwitterRequest alloc] init];
        (...);
        [t statuses_update:twittermessage.text delegate:self requestSelector:@selector(status_updateCallback:)];

        loadingActionSheet = [[UIActionSheet alloc] initWithTitle:@"Posting to Twitter..." delegate:nil 
                                                cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
        [loadingActionSheet showInView:self.view];
    }


    - (void) status_updateCallback: (NSData *) content {
        [loadingActionSheet dismissWithClickedButtonIndex:0 animated:YES];
        [loadingActionSheet release];
        NSLog(@"%@",[[NSString alloc] initWithData:content encoding:NSASCIIStringEncoding]);
    }

Но как я могу показать UIAlertView, когда имя пользователя / пароль были неверны? Вот TwitterRequest.m:

#import "TwitterRequest.h"

@implementation TwitterRequest

@synthesize username;
@synthesize password;
@synthesize receivedData;
@synthesize delegate;
@synthesize callback;
@synthesize errorCallback;

-(void)friends_timeline:(id)requestDelegate requestSelector:(SEL)requestSelector{
    isPost = NO;
    // Set the delegate and selector
    self.delegate = requestDelegate;
    self.callback = requestSelector;
    // The URL of the Twitter Request we intend to send
    NSURL *url = [NSURL URLWithString:@"http://twitter.com/statuses/friends_timeline.xml"];
    [self request:url];
}

-(void)statuses_update:(NSString *)status delegate:(id)requestDelegate requestSelector:(SEL)requestSelector; {
    isPost = YES;
    // Set the delegate and selector
    self.delegate = requestDelegate;
    self.callback = requestSelector;
    // The URL of the Twitter Request we intend to send
    NSURL *url = [NSURL URLWithString:@"http://twitter.com/statuses/update.xml"];
    requestBody = [NSString stringWithFormat:@"status=%@",status];
    [self request:url];
}

-(void)request:(NSURL *) url {
    theRequest   = [[NSMutableURLRequest alloc] initWithURL:url];

    if(isPost) {
        NSLog(@"ispost");
        [theRequest setHTTPMethod:@"POST"];
        [theRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [theRequest setHTTPBody:[requestBody dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]];
        [theRequest setValue:[NSString stringWithFormat:@"%d",[requestBody length] ] forHTTPHeaderField:@"Content-Length"];
    }

    theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

    if (theConnection) {
        // Create the NSMutableData that will hold
        // the received data
        // receivedData is declared as a method instance elsewhere
        receivedData=[[NSMutableData data] retain];
    } else {
        // inform the user that the download could not be made
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    //NSLog(@"challenged %@",[challenge proposedCredential] );

    if ([challenge previousFailureCount] == 0) {
        NSURLCredential *newCredential;
        newCredential=[NSURLCredential credentialWithUser:[self username]
                                                 password:[self password]
                                              persistence:NSURLCredentialPersistenceNone];
        [[challenge sender] useCredential:newCredential
               forAuthenticationChallenge:challenge];

    } else {
        [[challenge sender] cancelAuthenticationChallenge:challenge];
        // inform the user that the user name and password
        // in the preferences are incorrect
        NSLog(@"Invalid Username or Password"); //THIS MUST be important. The console shows this message, if the username/password is wrong. Here is also the place, where I set the bool to TRUE 
    }

}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    // this method is called when the server has determined that it
    // has enough information to create the NSURLResponse

    // it can be called multiple times, for example in the case of a
    // redirect, so each time we reset the data.
    // receivedData is declared as a method instance elsewhere
    //[receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    //NSLog([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    // append the new data to the receivedData
    // receivedData is declared as a method instance elsewhere
    [receivedData appendData:data];
}

- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error
{
    // release the connection, and the data object
    [connection release];
    // receivedData is declared as a method instance elsewhere
    [receivedData release];

    [theRequest release];

    // inform the user
    NSLog(@"Connection failed! Error - %@ %@",
          [error localizedDescription],
          [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);

    if(errorCallback) {
        [delegate performSelector:errorCallback withObject:error];
    }
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // do something with the data

    if(delegate && callback) {
        if([delegate respondsToSelector:self.callback]) {
            [delegate performSelector:self.callback withObject:receivedData];
        } else {
            NSLog(@"No response from delegate");
        }
    } 

    // release the connection, and the data object
    [theConnection release];
    [receivedData release];
    [theRequest release];
}

-(void) dealloc {
    [super dealloc];
}


@end

Я знаю, что важная строка в TwitterRequest.m находится в другой причине - (void) метода соединения, потому что Консоль всегда пишет неверное имя пользователя или пароль, когда они неверны. Поэтому я попытался указать в качестве свойства bool, который будет установлен в TRUE, когда имя / пароль неверны (= когда будет использоваться причина-другое). В моем ViewController я сделал это:

if (t.stimmtNicht == TRUE) {
    [loadingActionSheet dismissWithClickedButtonIndex:0 animated:YES];
    [loadingActionSheet release];
    UIAlertView *alert;
    alert = [[UIAlertView alloc] initWithTitle:@"Ouch!"
                                       message:@"Your Username or Password is wrong!"
                                      delegate:self 
                             cancelButtonTitle:@"OK" 
                             otherButtonTitles: nil];
    [alert show];   
    [alert release];
}

Но он всегда не использует причину, даже если пароль неправильный. Я думаю, что код проходит через if-очередь быстрее, чем TwitterRequest и устанавливает его в TRUE. Что я могу сделать?

Спасибо за вашу помощь и извините за этот глупый вопрос, но я изучаю Objective-C и программирование в целом всего одну неделю, и я не знаю, как правильно взаимодействовать из моего ViewController с другими классами.

Также извините за мой плохой английский!

1 Ответ

0 голосов
/ 06 января 2010

Два способа мыслить:

  1. Очевидно, у вашего класса TwitterRequest есть "делегат" ivar; попробуйте позвонить делегату, чтобы сказать ему (ей?), что ваши учетные данные неверны.
  2. Отправка NSNotification через NSNotificationCenter

В обоих случаях получающий уведомление класс должен отображать представление входа в систему (с полями имени пользователя и пароля), и все.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...