异步连接下载回调

时间:2014-06-16 21:32:03

标签: ios xcode asynchronous callback nsurlconnection

我使用以下方法创建了一个类customDownload:

-(NSString *) getTextFromLink: (PreliteRequest *) requestDetails
              asyncConnection: (BOOL) isAsync
               callbackMethod: (SEL) methodToExecute {

    mainRequest = requestDetails;

    NSMutableURLRequest *postRequest = [[NSMutableURLRequest alloc] init];
    NSURLRequest *getRequest = [[NSURLRequest alloc] init];
    NSURLConnection *connection;

    NSURLResponse * response = nil;
    NSError * error = nil;

    if ([[requestDetails getType] isEqualToString:@"POST"]) {
        [postRequest setURL:[NSURL URLWithString:[requestDetails getUrl]]];
        [postRequest setHTTPMethod:[requestDetails getType]];
        [postRequest setValue:[requestDetails getPostLenght] forHTTPHeaderField:@"Content-Length"];
        [postRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [postRequest setHTTPBody:[requestDetails getPostParameters]];

        if (isAsync) {
            tmpMethod = methodToExecute;
            connection = [[NSURLConnection alloc] initWithRequest:postRequest delegate:self];
        } else
            downloadedData = (NSMutableData *)[NSURLConnection sendSynchronousRequest:postRequest returningResponse:&response error:&error];
    } else {
        getRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@",[requestDetails getUrl],[requestDetails getGetParameters]]]];
        if (isAsync) {
            tmpMethod = methodToExecute;
            connection = [[NSURLConnection alloc] initWithRequest:getRequest delegate:self];
        } else
            downloadedData = (NSMutableData *)[NSURLConnection sendSynchronousRequest:getRequest returningResponse:&response error:&error];
    }

    NSString *result=[[NSString alloc]initWithData:downloadedData encoding:NSUTF8StringEncoding];

    return result;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    downloadedData = [[NSMutableData alloc] init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    // Append the new data to the instance variable you declared
    [downloadedData appendData:data];
}

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse*)cachedResponse {


    return nil;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

    NSString *tmpResult = [[NSString alloc]initWithData:downloadedData encoding:NSUTF8StringEncoding];

    [self performSelector:tmpMethod withObject:tmpResult];

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    NSLog(@"Connection error: %@",error);
}

在我的视图控制器中,我声明了上一个类,并调用了该类getTextFromLink的唯一方法。

download = [[customDownload alloc] init];
[download getTextFromLink:request asyncConnection:YES callbackMethod:tmpSelector];
SEL tmpSelector = @selector(printResult:);
-(void) printResult:(NSString *) resultToPrint {
    NSLog(@"Risultato: %@",resultToPrint);
}

我将tmpSelector传递给getTextFromLink作为参数,因为这是我想在getTextFromDownloadLink完成其工作后立即调用的方法。 实际上getTextFromLink执行异步连接。

我正在尝试做的是在异步连接完成下载数据时执行某些操作。 我想创建一个回调自定义类来执行此操作。

任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:2)

通常人们会使用块来代替这个选择器模型。例如,为您的块定义typedef

typedef void(^PreliteRequestCompletionHandler)(NSString *string);

由于您正在处理异步模式,因此您可能希望定义一个属性,您可以使用该属性来保存此完成处理程序以便稍后调用:

@property (nonatomic, copy) PreliteRequestCompletionHandler completionHandler;

然后,您可以将该选择器参数更改为块参数:

-(NSString *) getTextFromLink: (PreliteRequest *) requestDetails
              asyncConnection: (BOOL) isAsync
            completionHandler: (PreliteRequestCompletionHandler)completionHandler {

    self.completionHandler = completionHandler;

    // do stuff
}

然后,当你想要调用那个完成块时,你会做类似的事情:

NSString *result = ...;

if (self.completionHandler) {
    self.completionHandler(result);
}

然后,您现在可以将此新块参数用于您的方法:

download = [[customDownload alloc] init];
[download getTextFromLink:request asyncConnection:YES completionHandler:^(NSString *result) {
    NSLog(@"Risultato: %@", result);
}];