AFNetworking 完成后返回数据

Posted

技术标签:

【中文标题】AFNetworking 完成后返回数据【英文标题】:Return data after AFNetworking is done 【发布时间】:2014-05-06 08:39:21 【问题描述】:

我的代码出现异步问题。我在一堂课上收到了所有的网络请求。我的一个请求需要返回另一个类需要使用的 NSMutableArray。我的 webRequest 代码在这里:

- (NSMutableArray*) getTournamentsInClub:(NSString *)clubGUID withDelegateViewController:(UIViewController *)viewController 

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSMutableArray *responseArray = [[[NSMutableArray alloc] init] autorelease];
NSString *URL = [[NSString alloc]initWithFormat:@"SomeURL=%@",clubGUID];
[manager POST:URL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) 

    for (id obj in responseObject)
        //NSLog(@"obj: %@",[obj valueForKey:@"CustomerName"]);
        [responseArray addObject:obj];
    

 failure:^(AFHTTPRequestOperation *operation, NSError *error) 
    NSLog(@"Error: %@", error);
];
return responseArray;

我像这样从 viewController 调用方法:

[self handleClubTournaments:[[TournamentsWebService sharedToursWS] getTournamentsInClub:

//Show load screen. (hide in handler function)
GP_MobilAppDelegate *xdelegate = [[UIApplication sharedApplication] delegate];
[xdelegate showLoadingScreen:self.clubToursTableView andStatus:NSLocalizedString(@"loadTours", @"")];

我的 handleClubTournaments 函数如下所示:

-(void) handleClubTournaments:(id)result 

GP_MobilAppDelegate *xdelegate = [[UIApplication sharedApplication] delegate];

if([result isKindOfClass: [NSError class]]) 
    // If an error has occurred, handle it
    [xdelegate hideLoadingScreen];
    [[TournamentsWebService sharedToursWS] showErrorMessageAccordingToFault:result];
    return;


if([result isKindOfClass: [SoapFault class]]) 
    [xdelegate hideLoadingScreen];
    // If a server error has occurred, handle it
    [[TournamentsWebService sharedToursWS] showErrorMessageAccordingToFault:result];
    return;


//Do something with result...

if ([result count] > 0) 

    NSLog(@"Antal klubturneringer: %d", [result count]);
    //Start by removing excisting tours
    [self.tournamentsSourceArray removeAllObjects];
    NSMutableArray *tempArray=[NSMutableArray array];

    for (GGTournamentData *t in result)  //cast object in result list and add them to array

        [tempArray addObject:t];

    
    self.tournamentsSourceArray = [self sortByStringDate:tempArray]; //sort by date

    [tempArray release];

    NSLog(NSLocalizedString(@"tourLoadet", @""));


[self.clubToursTableView reloadData];
[xdelegate hideLoadingScreen];

//Scroll view
if (self.tournamentsSourceArray.count > 0)  //hvis det er turneringer..
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:[self findIndexOfMonthClosestToDate]];
    [self.clubToursTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];


所以我的问题是 NSMutableArray 在我的异步任务完成之前被返回。我知道异步任务的行为是这样的,但是如何确保我的 handleClubTournaments 函数在我的 webrequest(getTournamentsInClub) 获得一些数据之前不会运行?

提前致谢。

【问题讨论】:

【参考方案1】:

我认为您不知道异步操作是如何工作的。 NSMutableArray 永远不会被设置,因为它是同步返回的。 就您而言,我建议您与代表合作。

- (void)getTournamentsInClub:(NSString *)clubGUID withDelegateViewController:(UIViewController *)viewController completionBlock:(void (^)(NSMutableArray *result))completionBlock 
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    NSMutableArray *responseArray = [[[NSMutableArray alloc] init] autorelease];
    NSString *URL = [[NSString alloc]initWithFormat:@"SomeURL=%@",clubGUID];
    [manager POST:URL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) 

        for (id obj in responseObject) 
            [responseArray addObject:obj];
        

        // Request finished. Call the block.
        completionBlock(responseArray);

     failure:^(AFHTTPRequestOperation *operation, NSError *error) 
        NSLog(@"Error: %@", error);
    ];


- (void)handleClubTournaments 
    GP_MobilAppDelegate *xdelegate = [[UIApplication sharedApplication] delegate];
    [[TournamentsWebService sharedToursWS] getTournamentsInClub:^(NSMutableArray *result) 
    
         // Hide the Loading Indicator. Do something with the Result.
    ];

    // You can't access the result synchronously, therefore it's impossible to depend on it synchronously.

另一种异步返回数据的方法是块,类似于AFNetworking 解决方案。

您可以阅读更多关于如何开始使用块 here 以及如何使用委托 here。

【讨论】:

我对目标 c 编程很陌生 [self.delegate requestFinished:responseArray];像返回一样的功能?只是在任务完成之前它不会返回? 我尝试使用块来解决这个问题,但没有成功。再说一次,我很新,所以我不确定我做对了 查看我的编辑。你一定要阅读异步函数,因为它们很重要,我认为你不理解它们。 好的,我看到你链接了一些东西,我读了它们,非常感谢帮助。谢谢谢谢谢谢:) 嘿只是想让你知道我通过你发布的例子让它工作了我只是在调用者中做了一点更正,所以它修补了我需要传递的参数:[[TournamentsWebService sharedToursWS] getTournamentsInClub :[self.club valueForKey:@"GUID"] completionBlock:^(NSMutableArray *result)。因此,再次将其标记为正确答案。

以上是关于AFNetworking 完成后返回数据的主要内容,如果未能解决你的问题,请参考以下文章

AFNetworking 未在块内同步返回数据

我的返回数据表单 AFNetworking JSON 未正确显示

如何在afnetworking中的AFHTTPRequestOperationManager请求中获得返回

使用 AFNetworking 进行 Web 服务数据检索

iOS AFNetworking downloadProgressBlock 计算返回负数

最佳实践以及如何在 Symfony2 中找到从 iOS AFNetworking 获取 POST 数据并在 GET 中返回 JSON?