Question

Hi I have an app using ASIHTTPRequest to log-in to a web server. When the username and password are both correct, loginRequestFinished is called. However, When the log-in credentials are incorrect, neither the loginRequestFinished nor the loginRequestFailed are called.

I tried to get around this by implementing an NSTimer so that it will give an error message and cancel the request after 60s. However it looks like the request has already been dealloc by then (I found this weird as the loading indicator in the status bar is still spinning).

This is the error I got:

-[__NSCFTimer cancel]: unrecognized selector sent to instance 0x84f0720
(lldb) 

Here is my code:

- (void) login 
{    
    NSString* url = [NSString stringWithFormat:@"https://%@/local_login.html", self.serverIP];

    ASIHTTPRequest *theRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];
    [theRequest setDelegate:self];
    [theRequest setUsername:username];
    [theRequest setPassword:password];
    [theRequest setDidFinishSelector:@selector(loginRequestFinished:)];
    [theRequest setDidFailSelector:@selector(loginRequestFailed:)];
    [theRequest startAsynchronous];
    myTimer = [NSTimer scheduledTimerWithTimeInterval:60.0f
                                                        target:self
                                             selector:@selector(timerFired:)
                                                      userInfo:nil
                                                       repeats:NO];
}
- (void)timerFired:(ASIHTTPRequest *)request 
{
    [myTimer invalidate];
    UIAlertView *warning = [[[UIAlertView alloc] initWithTitle:@"Error" message:@"" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]autorelease];
    [warning show];
    [request cancel];
    [request release];
}

Any help will be appreciated

Update: I checked the server log. If I got the password or username incorrect, my app is sending login request to the server every second until I quit the iPhone Simulator.

2013-09-11 16:22:02.187 /local_login.html 401 91ms 0kb EC 1.0.1 (iPhone Simulator; iPhone OS 6.1; en_US)
  150.101.105.182 - - [11/Sep/2013:16:22:02 -0700] "GET /local_login.html HTTP/1.1" 401 404 - "EC 1.0.1 (iPhone Simulator; iPhone OS 6.1; en_US)" "xyz.appspot.com" ms=91 cpu_ms=0 cpm_usd=0.000045 app_engine_release=1.8.4 instance=00c71b118abd13a90c30bcf64033c95172a494
2013-09-11 16:22:01.754 /local_login.html 401 29ms 0kb EC 1.0.1 (iPhone Simulator; iPhone OS 6.1; en_US)
  150.101.105.182 - - [11/Sep/2013:16:22:01 -0700] "GET /local_login.html HTTP/1.1" 401 404 - "EC 1.0.1 (iPhone Simulator; iPhone OS 6.1; en_US)" "xyz.appspot.com" ms=30 cpu_ms=21 cpm_usd=0.000045 app_engine_release=1.8.4 instance=00c71b118abd13a90c30bcf64033c95172a494
(More Similar log events)

Thanks all. Issue have been resolved. It is the way that I passed in the ASIHTTPRequest to myTimer. I realized I have to use userInfo to passed in theRequest.

Was it helpful?

Solution

In the login method set the UserInfo for the timer. like below

 ASIHTTPRequest *theRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];



myTimer = [NSTimer scheduledTimerWithTimeInterval:60.0f
                                                        target:self
                                             selector:@selector(timerFired:)
                                                      userInfo:theRequest
                                                       repeats:NO];

why are you invalidating the timer if repeats:NO. If you set repeats to NO timer will be invalidated automatically.

- (void)timerFired:(NSTimer *)timer 
{
    ///[myTimer invalidate];  /// coment this. it will work.

    ASIHTTPRequest *request = (ASIHTTPRequest *)[timer userInfo];
    UIAlertView *warning = [[[UIAlertView alloc] initWithTitle:@"Error" message:@"" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]autorelease];
    [warning show];
    [request cancel]; 
    ///[request release]; ///request is an autorelease object
}

If you do this it should work properly.

Also in the see the argument in the method timerFired: timer is the argument that is passed, whenever the timerFired: method is invoked by the timer.

OTHER TIPS

Your login server may throw authentication challenge,Does it?

Why not use [theRequest setTimeOutSeconds:60]; instead of complexing with the timers - Crash issue is coz of timers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top