dhrm
dhrm

Reputation: 14934

ASIHTTPRequestTester: Asynchronous not working

I'm trying to make a App for iOS using ASIHTTPRequest, but I'm facing some issues using it. To demonstrate my problems, I've uploaded an test-project, which you can download from here: http://uploads.demaweb.dk/ASIHTTPRequestTester.zip.

I've created a WebService class which use the ASIHTTPRequestDelegate protocol:

#import "WebService.h"
#import "ASIHTTPRequest.h"

@implementation WebService

- (void)requestFinished:(ASIHTTPRequest *)request {
    NSLog(@"requestFinished");
}
- (void)requestFailed:(ASIHTTPRequest *)request {
    NSLog(@"requestFailed");
}

- (void) testSynchronous {
    NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
    NSLog(@"starting Synchronous");
    [request startSynchronous];
    NSError *error = [request error];
    if (!error) {
        NSLog(@"got response");
    }
}

- (void) testAsynchronous {
    NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
    [request setDelegate:self];

    NSLog(@"starting Asynchronous");
    [request startAsynchronous];
}

@end

The synchronous method is working fine, but the asynchronous is not working at all. First the requestFinished and requestFailed was never called and right now I'm getting an EXC_BAD_ACCESS. The two test-methods is called from my ViewController's viewDidLoad. I hope someone can help me making this work.

EDIT1: As per this topic, it is possible because of the Automatic Reference Counting which is enabled for my project. The topic advice to add a [self retain], but I cannot do this with ARC turned on. Anyone with a solution for this?

EDIT2: Update as per answer from MrMage.

@interface ViewController()
@property (nonatomic,strong) WebService *ws;
@end

@implementation ViewController

@synthesize ws = _ws;

#pragma mark - View lifecycle
- (void)viewDidLoad
{
    [super viewDidLoad];

    [self setWs:[[WebService alloc] init]];
    [self.ws testSynchronous];
    [self.ws testAsynchronous];
}

@end

Upvotes: 1

Views: 830

Answers (2)

Umeumeume
Umeumeume

Reputation: 1988

I got the same issue on delegation with ASIHTTPRequest and ARC.

I just end up using blocks to solve it.

NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];

//set request like this to avoid retain cycle on blocks
__weak ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

//if request succeeded
[request setCompletionBlock:^{        
    [self requestFinished:request];
}];

//if request failed
[request setFailedBlock:^{        
    [self requestFailed:request];
}];

[request startAsynchronous];

Upvotes: 0

MrMage
MrMage

Reputation: 7487

You could add your WebService instance as a strong reference to an object that stays around for long enough (say your view controller), then tell that class to get rid of the WebService after it has done its job (i.e. in requestFinished and requestFailed you call back to the view controller, telling it to release the WebService instance).

Upvotes: 3

Related Questions