0

I'm using RestKit 0.20. I'm trying to download the json response from the local rails application and save it to core-data. I tried to follow https://github.com/RestKit/RKGist/blob/master/TUTORIAL.md and everything worked fine.
I wanted to use this many times so i made it a base class(ListController) and subclassed it to SessionListController and EventListController. The mapping is provided in AppDelegate.m.

The app has a first viewcontroller which is the root controller which always maps the responses and everything works fine. But as soon as i change the viewcontroller i will get the response and the operation stops. it does't even say if the mapping has started. I'm not sure what i have missed.

Here i'm initialising restkit

AppDelegate.m

#import "AppDelegate.h"
#import <UIKit/UIKit.h>

@implementation AppDelegate   

RKEntityMapping *eventEntityMapping,*sessionEntitiyMapping;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSError *error = nil;
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"event" ofType:@"momd"]];
NSManagedObjectModel *managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
[self setManagedObjectStore: [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel]];

// Initialize the Core Data stack
[self.managedObjectStore createPersistentStoreCoordinator];

NSPersistentStore __unused *persistentStore = [self.managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(persistentStore, @"Failed to add persistent store: %@", error);

[self.managedObjectStore createManagedObjectContexts];

// Set the default store shared instance
[RKManagedObjectStore setDefaultStore:self.managedObjectStore];

NSString *url=@"http://192.168.11.11:3000";

RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:url]];
objectManager.managedObjectStore = self.managedObjectStore;

[RKObjectManager setSharedManager:objectManager];

[self mapEntities];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:eventEntityMapping pathPattern:@"/api/v1/events" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

[objectManager addResponseDescriptor:responseDescriptor];

RKResponseDescriptor *responseDescriptor2 = [RKResponseDescriptor responseDescriptorWithMapping:sessionEntitiyMapping pathPattern:@"/api/v1/sessions" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

[objectManager addResponseDescriptor:responseDescriptor2];


// Override point for customization after application launch.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
UINavigationController *navigationController = [storyboard instantiateViewControllerWithIdentifier:@"mainCenterController"];

IIViewDeckController* secondDeckController =  [[IIViewDeckController alloc] initWithCenterViewController:navigationController
                                                                                      leftViewController:[storyboard instantiateViewControllerWithIdentifier:@"sideBarController"]];
secondDeckController.centerhiddenInteractivity=IIViewDeckCenterHiddenNotUserInteractiveWithTapToClose;
self.window.rootViewController = secondDeckController;
return YES;
}

-(void)mapEntities{
//event
eventEntityMapping = [RKEntityMapping mappingForEntityForName:@"Event" inManagedObjectStore:self.managedObjectStore];
[eventEntityMapping addAttributeMappingsFromDictionary:@{
 @"id":             @"event_id",
 @"name":           @"name",
 @"description":    @"desc",
 @"no_of_days":     @"no_of_days",
 @"start_date":     @"start_date",
 }];
eventEntityMapping.identificationAttributes = @[ @"event_id" ];

sessionEntitiyMapping = [RKEntityMapping mappingForEntityForName:@"Session" inManagedObjectStore:self.managedObjectStore];
[sessionEntitiyMapping addAttributeMappingsFromDictionary:@{
 @"name":           @"name",
 @"description":    @"desc",
 @"start_time":     @"start_time",
 @"duration":       @"duration",
 @"location_id":    @"location_id",
 @"event_id":       @"event_id",
 @"id":             @"session_id",
 }];
sessionEntitiyMapping.identificationAttributes = @[ @"session_id" ];
}

Base class where i'm calling getObjectsAtPath for RKManager depending on the base class.

ListController.m

@implementation ListController
- (void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = appDelegate.managedObjectStore.mainQueueManagedObjectContext;
[self loadLocs];
[self.refreshControl beginRefreshing];
}

-(void)setModel:(Models)model{
if(self.model!=model){
    _model=model;
    self.title=[Model displayFor:self.model];
    _fetchedResultsController = nil;
    [self.tableView reloadData];
    [self loadLocs];
    [self.refreshControl beginRefreshing];
}
}

- (void)loadLocs
{
[[RKObjectManager sharedManager] getObjectsAtPath:[Model listApiFor:self.model]
                                       parameters:nil
                                          success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                                              [self.refreshControl endRefreshing];
                                          }
                                          failure:^(RKObjectRequestOperation *operation, NSError *error) {
                                              [self.refreshControl endRefreshing];
                                              UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An Error Has Occurred" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
                                              NSLog(@"error: %@",error);
                                              [alertView show];
                                          }];
}


#pragma mark - Table View

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[[self fetchedRCforTableView:tableView] sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
[self configureCell:cell atIndexPath:indexPath forTableView:tableView];
return cell;
}

#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
    return _fetchedResultsController;
}

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:[Model entityFor:self.model] inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];

// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:[Model sortDescriptorFor:self.model] ascending:YES];
NSArray *sortDescriptors = @[sortDescriptor];

[fetchRequest setSortDescriptors:sortDescriptors];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:[Model displayFor:self.model]];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
NSLog(@"_fetchedResultsController count %d",_fetchedResultsController.fetchedObjects.count);
return _fetchedResultsController;
}

@end

This is one of the base classes where i set the model name

EventViewController.m

- (void)viewDidLoad
{
[super viewDidLoad];
self.model=Eventm;
// Do any additional setup after loading the view.
}

SessionViewController.m

- (void)viewDidLoad
{
[super viewDidLoad];
self.model=Sessionm;
// Do any additional setup after loading the view.
}

Full code is at https://github.com/leohemanth/event-app

After using

RKLogConfigureByName("RestKit", RKLogLevelWarning);
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);

I can see that, i'm getting proper Http response but it is not being mapped. Which i'm not sure why?

hemanth
  • 189
  • 2
  • 13
  • Does the log say that sometimes it can't find a response descriptor? Or that no keypaths match? Need some log to go on or sample JSON to compare to. – Wain May 14 '13 at 20:41
  • No the log don't have any error message. It just stops after logging the response text. Example json reponse for event is https://gist.github.com/leohemanth/5579457 – hemanth May 14 '13 at 20:51
  • What's the code for listApiFor: - what path does it return ? – Wain May 14 '13 at 21:01
  • listApiFor returns api path for event - _return @"/api/v1/events"_ and for session _return @"/api/v1/sessions"_ – hemanth May 14 '13 at 21:07
  • When defining the response descriptors, specify the path patterns without the leading '/'. It seems very strange that you get no log information with trace logging on, usually it tells you exactly where the issue is. – Wain May 14 '13 at 21:09
  • Are you sure that might cause the problem? Because even in https://github.com/RestKit/RKGist/blob/master/TUTORIAL.md the leading '/' is used. and i'm getting some error (NSUnknownKeyException) if the remove the leading '/' – hemanth May 14 '13 at 21:33
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/29946/discussion-between-wain-and-hemanth) – Wain May 14 '13 at 21:33

1 Answers1

0

I've just updated my Restkit package to 0.20.2. I'm not facing the problem now. It should be fixed in the update.

hemanth
  • 189
  • 2
  • 13