Search code examples
iosjsonmappingrestkitcllocation

RestKit RKObjectMapping to CLLocation


I am using RestKit's Object Mapping to map JSON data to an object. Is it possible to map the latitude and longitude JSON attributes to a CLLocation variable in my Objective-C class?

The JSON:

{ "items": [
    {
        "id": 1,
        "latitude": "48.197186",
        "longitude": "16.267452"
    },
    {
        "id": 2,
        "latitude": "48.199615",
        "longitude": "16.309645"
    }
]

}

The class it should be mapped to:

@interface ItemClass : NSObject    
  @property (nonatomic, strong) CLLocation *location;
@end

In the end I'd like to call itemClassObj.location.longitude getting me the value of the latitude from the JSON response.

I thought something like this would work, but it doesn't.

RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[ItemClass class]];
[mapping mapKeyPath:@"latitude" toAttribute:@"location.latitude"];
[mapping mapKeyPath:@"longitude" toAttribute:@"location.longitude"];

Thanks a lot for your help.


Solution

  • To create a CLLocation you need both the latitude and the longitude at the same time. Moreover, the coordinates for CLLocation (like CLLocationCoordinate2D) aren't NSNumbers, they're double floats, so it can jack up the key value compliance in mapping like this because floats aren't objects.

    Most often, people will store a latitude and longitude in a class as NSNumbers and then build the CLLocationCoordinate2D coordinate on demand after the class object is instantiated/populated.

    What you could do, if you were so inclined, is utilize the willMapData: delegate method to snoop the data coming in, in order to manually populate a CLLocation ... but to me this is overkill and requires too much overhead.


    EDIT: Adding this because comments don't format code property...

    Or, you could put something like this in your object class implementation and interface...

    @property (nonatomic,readonly) CLLocationCoordinate2D coordinate;
    
    - (CLLocationCoordinate2D)coordinate {
        CLLocationDegrees lat = [self.latitude doubleValue];
        CLLocationDegrees lon = [self.longitude doubleValue];
        CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(lat, lon);
        if (NO == CLLocationCoordinate2DIsValid(coord))
            NSLog(@"Invalid Centroid: lat=%lf lon=%lf", lat, lon);
        return coord;
    }