我正在将我的应用程序例程从ASIHTTP转换为AFNetworking,原因是该项目的工作不幸中断......以及我后来发现的AFNetworking更好更小的代码库。
我发现了几个问题。我的ASIHTTPRequest代码是作为一种方法构建的。此方法采用一些参数并将参数发布到URL ...返回结果数据。这些数据总是文本,但为了制作通用方法,有时可能是json,有时是XML,有时是HTML。因此,我将此方法构建为独立的通用URL下载程序。
我的问题是,当调用例程时,我有等待响应。我知道所有“同步都不好”的论点......而且我不做很多...但对于某些方法我想要同步。
所以,这是我的问题。我的简化ASIHTTP代码如下,其次是我能想到在AFNetworking中编码的唯一方法。我遇到的问题是AFNetworking有时不会在从方法返回之前进行响应。 @mattt给出[operation waitUntilFinished]
的提示完全无法保持线程,直到调用完成块...而我的[queue waitUntilAllOperationsAreFinished]
的另一种方法不一定总能工作(并且不会导致触发) [operation hasAcceptableStatusCode]子句的错误部分)。所以,如果有人可以提供帮助,那么无论如何“异步设计它”,请做。
ASIHTTP版本:
- (NSString *) queryChatSystem:(NSMutableDictionary *) theDict
{
NSString *response = [NSString stringWithString:@""];
NSString *theUrlString = [NSString stringWithFormat:@"%@%@",kDataDomain,kPathToChatScript];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:theUrlString]];
for (id key in theDict)
{
[request setPostValue:[theDict objectForKey:key] forKey:key];
}
[request setNumberOfTimesToRetryOnTimeout:3];
[request setAllowCompressedResponse:YES];
[request startSynchronous];
NSError *error = [request error];
if (! error)
{
response = [request responseString];
}
return response;
}
AFNetworking版
- (NSString *) af_queryChatSystem:(NSMutableDictionary *) theDict
{
NSMutableDictionary *theParams = [NSMutableDictionary dictionaryWithCapacity:1];
for (id key in theDict)
{
[theParams setObject:[theDict objectForKey:key] forKey:key];
}
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:kDataDomain]];
NSMutableURLRequest *theRequest = [httpClient requestWithMethod:@"POST" path:[NSString stringWithFormat:@"/%@",kPathToChatScript] parameters:theParams];
__block NSString *responseString = [NSString stringWithString:@""];
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:theRequest] autorelease];
operation.completionBlock = ^ {
if ([operation hasAcceptableStatusCode]) {
responseString = [operation responseString];
NSLog(@"hasAcceptableStatusCode: %@",responseString);
}
else
{
NSLog(@"[Error]: (%@ %@) %@", [operation.request HTTPMethod], [[operation.request URL] relativePath], operation.error);
}
};
NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
[queue addOperation:operation];
[queue waitUntilAllOperationsAreFinished];
[httpClient release];
return responseString;
}
非常感谢任何想法。
答案 0 :(得分:3)
- (void)af_queryChatSystem:(NSMutableDictionary *) theDict block:(void (^)(NSString *string))block {
...
}
现在在completionBlock中执行:
block(operation.responseString);
块将充当操作的委托。删除
-waitUntilAllOperationsAreFinished
和
return responseString
你称之为:
[YourInstance af_queryChatSystem:Dict block:^(NSString *string) {
// use string here
}];
希望它有所帮助。您可以参考AFNetworking的iOS示例
答案 1 :(得分:0)
我强烈建议您利用这个机会转换为Apple自己的NSURLConnection
,而不是采用另一个第三方API。通过这种方式,您可以确定它不会停止。我发现使其工作所需的额外工作是最小 - 但事实证明它更加强大且不易出错。
答案 2 :(得分:0)
我的解决方案是手动运行当前线程runloop,直到回调处理完毕。
这是我的代码。
- (void)testRequest
{
MyHTTPClient* api = [MyHTTPClient sharedInstance]; // subclass of AFHTTPClient
NSDictionary* parameters = [NSDictionary dictionary]; // add query parameters to this dict.
__block int status = 0;
AFJSONRequestOperation* request = [api getPath:@"path/to/test"
parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// success code
status = 1;
NSLog(@"succeeded");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// failure
status = 2;
NSLog(@"failed");
}];
[api enqueueHTTPRequestOperation:request];
[api.operationQueue waitUntilAllOperationsAreFinished];
while (status == 0)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate date]];
}
STAssertEquals(status, 1, @"success block was executed");
}