ecordell / RestKit

RestKit is a framework for consuming and modeling restful web resources on OS X and iPhone/iPad
http://www.twotoasters.com/
Apache License 2.0
15 stars 1 forks source link

Some requests fired to bad url after offline period. #5

Open sebfie opened 12 years ago

sebfie commented 12 years ago

Hello,

As you know, i am using your sync branch for my first iOS app :) (In production in two weeks). After a offline period, when i got internet again, i have my requests in queue fired (regular way) but also others to strange url (like my model id was 0).

I have a model Card, and i got 2 requests to cards/0.json with no parameters. I tried to change the id field to identify, but no changes.

I configured my model like that :

- (void) initCardMapping
{
/* ROUTER */
RKObjectRouter *router = [RKObjectManager sharedManager].router;
// Define a default resource path for all unspecified HTTP verbs
[router routeClass:[Card class] toResourcePath:@"/cards/:id\\.json" forMethod:RKRequestMethodGET];
[router routeClass:[Card class] toResourcePath:@"/cards.json" forMethod:RKRequestMethodPOST];
[router routeClass:[Card class] toResourcePath:@"/cards/:id\\.json" forMethod:RKRequestMethodPUT];
[router routeClass:[Card class] toResourcePath:@"/cards/:id\\.json" forMethod:RKRequestMethodDELETE];

/* MAPPING */
RKManagedObjectMapping *mapping = [Card getMapping];
mapping.syncMode = RKSyncModeTransparent;

[[RKObjectManager sharedManager].mappingProvider setSerializationMapping:mapping forClass:[Card class]]; 
[[RKObjectManager sharedManager].mappingProvider registerMapping:mapping withRootKeyPath:@"card"];
[[RKObjectManager sharedManager].mappingProvider setMapping:mapping forKeyPath:@"cards"]; 
}

It comes when i specify : mapping.syncMode = RKSyncModeTransparent;

Any idea?

I tried with an empty database (no card model), and it also happens. It's a GET request.

ecordell commented 12 years ago

Can you show me what your actual mapping looks like (in [Card getMapping])? Also it would be really useful to see some logs about what's going on. You can turn RestKit logs on by writing:

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

I usually put it in appDidFinishLaunching:withOptions:

Without those two things it's really hard to tell what the problem might be. One thing that I see right away is that you're using mapping for both the serialization mapping and the regular mapping - if you set it just to regular mapping, it automatically serializes using [mapping inverseMapping]. Here you've overridden that default be setting the serialization to mapping, which is the opposite of what you want, so I'm frankly surprised it works at all.

And I still find the use of "id" concerning, but I guess if it works it works. If you're new to Objective-C, id is a type specifier for variables that can hold any type of Objective-C object.

sebfie commented 12 years ago

So, this is my [Card getMapping] function; i made it just because i prefer to keep each model mapping on the model file :

 +(RKManagedObjectMapping *) getMapping 
   {
    //Card Mapping
    RKManagedObjectMapping* mapping = [RKManagedObjectMapping mappingForClass:[self class] inManagedObjectStore:[[RKObjectManager sharedManager] objectStore]];
    mapping.primaryKeyAttribute = @"id";

    [mapping mapKeyPath:@"id" toAttribute:@"id"];
    [mapping mapKeyPath:@"date" toAttribute:@"date"];
    [mapping mapKeyPath:@"start_time" toAttribute:@"start_time"];
    [mapping mapKeyPath:@"end_time" toAttribute:@"end_time"];
    [mapping mapKeyPath:@"water_used" toAttribute:@"water_used"];
    [mapping mapKeyPath:@"electricity_day_used" toAttribute:@"electricity_day_used"];
    [mapping mapKeyPath:@"electricity_night_used" toAttribute:@"electricity_night_used"];
    [mapping mapKeyPath:@"heater" toAttribute:@"heater"];
    [mapping mapKeyPath:@"ph" toAttribute:@"ph"];
    [mapping mapKeyPath:@"chlore" toAttribute:@"chlore"];
    [mapping mapKeyPath:@"cyanuric_acid" toAttribute:@"cyanuric_acid"];
    [mapping mapKeyPath:@"continue_filtering" toAttribute:@"continue_filtering"];
    [mapping mapKeyPath:@"filtering_start" toAttribute:@"filtering_start"];
    [mapping mapKeyPath:@"filtering_end" toAttribute:@"filtering_end"];
    [mapping mapKeyPath:@"water_quality" toAttribute:@"water_quality"];
    [mapping mapKeyPath:@"furniture" toAttribute:@"furniture"];
    [mapping mapKeyPath:@"furniture_to_get" toAttribute:@"furniture_to_get"];
    [mapping mapKeyPath:@"miscellaneous" toAttribute:@"miscellaneous"];
    [mapping mapKeyPath:@"treatment_chlore" toAttribute:@"treatment_chlore"];
    [mapping mapKeyPath:@"treatment_pebble" toAttribute:@"treatment_pebble"];
    [mapping mapKeyPath:@"treatment_hypochlorite" toAttribute:@"treatment_hypochlorite"];
    [mapping mapKeyPath:@"treatment_anti_algae" toAttribute:@"treatment_anti_algae"];
    [mapping mapKeyPath:@"treatment_ph_plus" toAttribute:@"treatment_ph_plus"];
    [mapping mapKeyPath:@"treatment_ph_less" toAttribute:@"treatment_ph_less"];
    [mapping mapKeyPath:@"treatment_floculant" toAttribute:@"treatment_floculant"];
    [mapping mapKeyPath:@"treatment_filling_start" toAttribute:@"treatment_filling_start"];
    [mapping mapKeyPath:@"treatment_auto_stop_filling" toAttribute:@"treatment_auto_stop_filling"];
    [mapping mapKeyPath:@"regulation_temperature" toAttribute:@"regulation_temperature"]; 
    [mapping mapKeyPath:@"created_at" toAttribute:@"created_at"];
    [mapping mapKeyPath:@"updated_at" toAttribute:@"updated_at"];
    [mapping mapKeyPath:@"team_id" toAttribute:@"team_id"];

    [mapping mapRelationship:@"customer" withMapping:[Customer getMapping]];
    [mapping mapKeyPath:@"tasks" toRelationship:@"works" withMapping:[Work getMapping]];
    return mapping;
}

When i launch my app, it sends two GET requests on cards/0.json. You can find my log :

https://gist.github.com/0919cf0cd7d0a7e49bbd

(I don't have any ManagedObjectSyncQueue in my .sqlite)

sebfie commented 12 years ago

Each of this two lines :

[[RKObjectManager sharedManager].mappingProvider registerMapping:mapping withRootKeyPath:@"card"];
[[RKObjectManager sharedManager].mappingProvider setMapping:mapping forKeyPath:@"cards"]; 

Each makes a GET request, any idea why?

When i delete this lines, requests disappear but application no longer works :)

So, when i do : [[RKObjectManager sharedManager] loadObjectsAtResourcePath:[@"/cards.json" appendQueryParams:dict] delegate:self];

I have 3 requests to /cards.json

sebfie commented 12 years ago

My error maybe comes from the router,

  [router routeClass:[Card class] toResourcePath:@"/cards/:id\\.json" forMethod:RKRequestMethodGET];

it's not

   [router routeClass:[Card class] toResourcePath:@"/cards.json" forMethod:RKRequestMethodGET];

??

sebfie commented 11 years ago

Is now you work merges with the restkit master branch?