ios - 在 ViewController 中将 API 数据发送到 UITableView

标签 ios objective-c json uitableview google-places-api

无法使用来自 Google Places API 的数据填充 ViewController(而非 TableViewController)中的 TableView。

我已经成功地提取数据并将 JSON 解析为带有注释的 MKMapView,所以我知道这部分工作正常,但我希望数据也流入其下方的表格(见图)。

Example layout of MapView with TableView below

我到处寻找有关如何执行此操作的简单说明。甚至遵循了一个教程(但它是针对 TableViewController 的,所以我希望我的问题只是我链接它的方式)。另一种可能性是放置我的 [self.tableView reloadData]; 调用。这对我来说是合乎逻辑的,但很可能是在错误的地方。显然,如果 TableView 的位置不正确,它会保持空白,但我已经在几个地方尝试过了。

注意:我只包含了相关代码,希望能让你们更容易发现。 TableView 对象连接到 ViewController 作为其数据源和委托(delegate),原型(prototype)单元格在属性编辑器中称为“Cell”,如 #pragma 代码中所调用,JSON 数据存储在名为“places”的 NSArray 中。如果您发现我遗漏的愚蠢行为导致此方法无法正常工作,请告诉我,在此先感谢您。

ViewController.h

@interface RendezvousViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>

@property (strong, nonatomic)          NSArray *places;
@property (strong, nonatomic) IBOutlet UITableView *tableView;

ViewController.m

    -(void)viewDidLoad {
        self.tableView.dataSource = self;
        self.tableView.delegate = self;
}    

    -(void) queryGooglePlaces: (NSString *) googleType {
            // Build the url string to send to Google.
            NSString *url = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=%f,%f&radius=%@&types=food|restaurant|bar&sensor=true&keyword=%@&key=%@",currentCentre.latitude,currentC

entre.longitude,[NSString stringWithFormat:@"%i",currenDist],selection, kGOOGLE_API_KEY];
        url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

        NSLog(@"%@", url);

        //Formulate the string as a URL object.
        NSURL *googleRequestURL=[NSURL URLWithString:url];

        // Retrieve the results of the URL.
        dispatch_async(kBgQueue, ^{
            NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
            [self performSelectorOnMainThread:@selector(fetchedData:) withObject:data waitUntilDone:YES];

        });
    }

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

                                  options:kNilOptions
                                  error:&error];

            //The results from Google will be an array obtained from the NSDictionary object with the key "results".
            NSArray* places = [json objectForKey:@"results"];

            //Write out the data to the console.
            NSLog(@"Google Data: %@", places);

            [self plotPositions:places];
            [self.tableView reloadData];
        }

    #pragma mark - Table view data source

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        // Return the number of sections.
        return 1;
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        // Return the number of rows in the section.
        return [self.places count];
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

        NSDictionary *tempDictionary= [self.places objectAtIndex:indexPath.row];

        cell.textLabel.text = [tempDictionary objectForKey:@"name"];

        if([tempDictionary objectForKey:@"rating"] != NULL)
        {
            cell.detailTextLabel.text = [NSString stringWithFormat:@"Rating: %@ of 5",[tempDictionary   objectForKey:@"rating"]];
        }
        else
        {
            cell.detailTextLabel.text = [NSString stringWithFormat:@"Not Rated"];
        }

        return cell;
    }

最佳答案

看起来你的 dispatch_async 调用有问题。

现在一旦您获得数据,您应该从 mainThread 中填充它。

您必须将调用修改为:

dispatch_async(kBgQueue, ^{
    NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
    dispatch_sync(dispatch_get_main_queue(), ^{
        [self fetchedData:data];
    });
});

这将确保 [self fetchedData:data]; 仅在您在后台线程中完成从 google 加载数据时被调用。

这是我的 live 的类似结果示例。

enter image description here

代码中还有一个错误:将此 NSArray* places = [json objectForKey:@"results"]; 更改为 self.places = [json objectForKey:@"results"];

希望对您有所帮助。

关于ios - 在 ViewController 中将 API 数据发送到 UITableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21143428/

相关文章:

ios - 在推送时制作一个透明的导航栏并在弹出时恢复它

ios - Xamarin 窗体 : How to override the OnBackButtonPressed on iOS

html - 修复了当我在 iOS Safari 9+ 中快速滚动到底部时元素不可点击的问题

ios - 重新加载和调用 requestImageForAsset 时 UICollectionView 闪烁

iphone - NSString 包含 : <null> and is crashing my app

c++ - 如何使用 json11 库修改 json 对象?

javascript - Node JS 应用程序仅显示第一个 JSON 对象。为什么?

ios - 在 Swift 中动态创建自定义按钮的实例

objective-c - 水平镜像 SKSpriteNode 纹理

php - 从 android 到 JSON 到 mysql Arabic