Ios 异步连接下载回调
我使用以下方法创建了customDownload类:Ios 异步连接下载回调,ios,xcode,asynchronous,callback,nsurlconnection,Ios,Xcode,Asynchronous,Callback,Nsurlconnection,我使用以下方法创建了customDownload类: -(NSString *) getTextFromLink: (PreliteRequest *) requestDetails asyncConnection: (BOOL) isAsync callbackMethod: (SEL) methodToExecute { mainRequest = requestDetails; NSMutableURLReque
-(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执行一个异步连接
我试图做的是在异步连接完成下载数据时执行一些操作。
我想创建一个回调自定义类来实现这一点
有人能帮我吗?通常人们会使用块来实现这一点,而不是使用这种选择器模型。例如,为块定义
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);
}];
与您手头的问题无关,但我建议更改
PreliteRequest
以消除这些getType
、getUrl
等方法,只需将其定义为具有type
、url
属性,并使用标准的getter即可。@prelite BTW,我使用了一个NSString*
作为完成处理程序的参数,因为您的示例就是这样使用的,但是您可能需要两个参数,一个NSString
(如果成功),一个NSError
(这是Cocoa通常使用的模式)。或者,您可以使用单独的故障处理程序块(AFNetworking使用的模式)。这两种方法都可以,但无论哪种方法,您都希望调用getTextFromLink
的代码能够检测和处理错误。非常感谢您。。。它工作得很好…从现在起我不知道你是什么块刚刚打开了一个新的世界给我…再次感谢…罗伯,你能解释一下为什么你有“复制”限定符为你的PreliteRequestCompletionHandler。当我看到你的答案时,我正要发布一个类似的答案。“我没有使用拷贝,而且它似乎工作得很好。”苹果公司说注意:您应该指定copy
作为属性属性,因为需要复制块以跟踪其原始范围之外的捕获状态。在使用自动引用计数时,您不必担心这一点,因为它会自动发生,但属性属性显示结果行为是最佳做法。“使用完成处理程序,大括号内的所有代码都将在另一个线程中异步执行……我尝试过,效果很好,但如果我想在完成处理程序内传递一些参数(我是指调用带有完成处理程序的异步连接的方法的变量),我怎么能不使用singleton?