Search code examples
iosxcodejsonuitableviewrestkit

UITableView not pulling JSON in correctly


EDIT- Solved: I added a Model for "Feed" which took care of the mapping problem I was having. Thanks!

I want to display all of the "Headline" in UITableView rows, but I'm getting a crash:

WebListViewController.m -

@interface WebListViewController ()

@property (strong, nonatomic) NSArray *headlinesNow;

@end

@implementation WebListViewController

@synthesize tableView = _tableView;
@synthesize headlinesNow;

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *lAbbreviation = [defaults objectForKey:@"lAbbreviation1"];
    NSString *tID = [defaults objectForKey:@"tId1"];

 NSString *url = [NSString stringWithFormat:@"/now/?l=%@&t=%@&apikey=5xxxxxxxx", lAbbreviation, tID];
    [[RKObjectManager sharedManager] loadObjectsAtResourcePath:url usingBlock:^(RKObjectLoader *loader)  {
        loader.onDidLoadObjects = ^(NSArray *objects) {

headlinesNow = objects;

[_tableView reloadData];

[loader.mappingProvider setMapping:[Headline mapping] forKeyPath:@"feed.headline"];
        loader.onDidLoadResponse = ^(RKResponse *response){
            NSLog(@"BodyAsString: %@", [response bodyAsString]);
        };
    }];

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    return headlinesNow.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    static NSString *CellIdentifier = @"standardCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    Headline *headlineLocal = [headlinesNow objectAtIndex:indexPath.row];
    NSString *headlineText = [NSString stringWithFormat:@"%@", headlineLocal.headline];
    cell.textLabel.text = headlineText;
    return cell;
}

Headline.h

@interface Headline : NSObject
@property (strong, nonatomic) NSString *headline;
@property (strong, nonatomic) Links *linksHeadline;
+ (RKObjectMapping *) mapping;
@end

Headline.m

@implementation Headline
+ (RKObjectMapping *)mapping {
    RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[self class] usingBlock:^(RKObjectMapping *mapping) {
        [mapping mapKeyPathsToAttributes:
         @"headline", @"headline",
         nil];
        [mapping hasOne:@"links" withMapping:[Links mapping]];
    }];
    return objectMapping;
}
@end

JSON Response Body -

{
    "timestamp": "2013-05-03T22:03:45Z",
    "resultsOffset": 0,
    "status": "success",
    "resultsLimit": 10,
    "breakingNews": [],
    "resultsCount": 341,
    "feed": [{
        "headline": "This is the first headline",
        "lastModified": "2013-05-03T21:33:32Z",
        "premium": false,
        "links": {
            "api": {

I'm getting the NSLog output for bodyAsResponse, but the program is crashing and not filling in the UITableView. I'm obviously not navigating into the JSON correctly? Any ideas?

Appreciate the help, let me know if you need any more code snippets-

EDIT- Crash is: Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0xe693110> valueForUndefinedKey:]: this class is not key value coding-compliant for the key headline.'


Solution

  • The first problem is your current forKeyPath:@"feed.headline". It should just be forKeyPath:@"feed" as that keypath isn't valid for your JSON. The reason is that feed in your JSON is an array so it should map to your Headline object, then your mapping definition for that object will be used for the headline.

    Next issue is the linksHeadline attribute and the [mapping hasOne:@"links" withMapping:[Links mapping]];. The key names don't match. Change the property name in Headline to be links.