UIRefreshControl 带有两个异步 json 下载来填充 UITableView 行和自定义标题视图

Posted

技术标签:

【中文标题】UIRefreshControl 带有两个异步 json 下载来填充 UITableView 行和自定义标题视图【英文标题】:UIRefreshControl with two async json downloads to populate UITableView rows and custom header view 【发布时间】:2013-11-25 17:57:02 【问题描述】:

我有一个UITableViewController,它可以从正常工作的 WS json 中获取它的信息。

现在我需要在UIRefreshControl pull 上使用两个不同的 WS 调用填充表格和表格的标题视图。

-(void)refreshView:(UIRefreshControl *)refresh         
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^

            __block NSData *data = [self fetchNewData];
            dispatch_async(dispatch_get_main_queue(), ^
                if (data) 
                    [self fetchedData:data];
                    [self.tableView reloadData];
                 else 
                    //show error    
                

                [self.refreshControl endRefreshing];
            );
    );



-(NSData*)fetchNewData 
    NSString *api = SINGLE URL;
    if (api) 
        NSData* data = [NSData dataWithContentsOfURL:
                        [NSURL URLWithString:api]];
        return data;
     else 
        return nil; //alert
    


- (void)fetchedData:(NSData *)responseData 
    //parse out the json data
    NSError* error = nil;
        _JSONDict = [NSJSONSerialization
                     JSONObjectWithData:responseData

                     options:kNilOptions
                     error:&error];

        _tableDataRows = [_JSONDict objectForKey:@"tableDataRows"];    
    

最后,- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 使用_tableDataRows 填充表格。

现在,我想在 UIRefreshControl 的同一个“拉动”上更新表格标题视图上的一些标签,这是来自 ViewController 的自定义视图,来自第二个 API URL json,这意味着加载动画应该一直打开,直到两个 json 都被下载和解析。最好的方法是什么?

如果您需要更多信息,请告诉我.. 谢谢!

【问题讨论】:

你为什么不把你的 WS 调用放在同一个控制器中呢?一个接一个地叫他们? (在重新加载 tableview 之前) 您可以使用调度组link @adriencog 你到底是什么意思?您会将第二个 WS 调用放在哪里?如果我一个接一个地放置,我认为它们实际上会一个接一个地进行,我希望同时异步地进行。 @Greg 我喜欢这样!修改起来很简单,我想,稍后会返回我的结果,谢谢! 【参考方案1】:

阅读@Greg 的评论链接和另一个Q:Waiting until two async blocks are executed before starting another block

我想出了这个以我想要的方式工作的方法:

-(void)refreshView:(UIRefreshControl *)refresh 

dispatch_group_t group = dispatch_group_create();
__block BOOL isReachable = NO;
__block NSData *data = nil;
__block NSData *dataPublic = nil;

dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ 
    isReachable = [self.appDelegate isReachable];
);

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ 
    if (isReachable) 
        data = [self fetchNewData];
    
);

dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ 
    if (isReachable) 
        dataPublic = [self fetchPublicData];
    
);

dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ 
    if (isReachable) 
        dispatch_async(dispatch_get_main_queue(), ^
            //Public data
            if (dataPublic) 
                [self fetchedPublicData:dataPublic];
             else 
                //handle error                    
            
            //User data
            if (data) 
                [self fetchedData:data];
                [self.tableView reloadData];
             else 
                //handle error                    
            

            [self.refreshControl endRefreshing];
        );
     else 
        dispatch_async(dispatch_get_main_queue(), ^
            [self.refreshControl endRefreshing];
            [self.appDelegate showConnectionErrorAlert];
        );
    

);


请随时提出改进建议!

【讨论】:

以上是关于UIRefreshControl 带有两个异步 json 下载来填充 UITableView 行和自定义标题视图的主要内容,如果未能解决你的问题,请参考以下文章

带有 RxSwift 的 UIRefreshControl

UITableView - 带有背景图像的 UIRefreshControl

Swift Firebase:带有 .childAdded 的 UIRefreshControl

UIRefreshControl 在带有大标题的 UINavigation 后面呈现

UIRefreshControl 未在 iOS 10 以下显示带有 DialogViewController 的 Xamarin

拉动刷新后,带有 UiRefreshControl 的 Tableview 卡住了