RestKit RKObjectMapping на CLLocation - PullRequest
       15

RestKit RKObjectMapping на CLLocation

1 голос
/ 06 ноября 2011

Я использую сопоставление объектов RestKit для сопоставления данных JSON с объектом. Можно ли отобразить атрибуты JSON широты и долготы в переменную CLLocation в моем классе Objective-C?

JSON:

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

}

Класс, к которому он должен быть привязан:

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

В конце я хотел бы позвонить itemClassObj.location.longitude и получить значение широты из ответа JSON.

Я думал, что-то вроде этого будет работать, но это не так.

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

Большое спасибо за вашу помощь.

Ответы [ 2 ]

3 голосов
/ 21 мая 2014

RestKit добавил ValueTransformer специально для CLLocation:

https://github.com/RestKit/RKCLLocationValueTransformer

Приведенный пример JSON:

{
    "user": {
        "name": "Blake Watters",
        "location": {
            "latitude": "40.708",
            "longitude": "74.012"
        }
    }
}

Чтобы отобразить из данного JSON объекта User:

@interface User : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) CLLocation *location;
@end

Использовать RKCLLocationValueTransformer:

#import "RKCLLocationValueTransformer.h"

RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:[User class]];
[userMapping addAttributeMappingsFromArray:@[ @"name" ]];
RKAttributeMapping *attributeMapping = [RKAttributeMapping attributeMappingFromKeyPath:@"location" toKeyPath:@"location"];
attributeMapping.valueTransformer = [RKCLLocationValueTransformer locationValueTransformerWithLatitudeKey:@"latitude" longitudeKey:@"longitude"];
[userMapping addPropertyMapping:attributeMapping];

RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"user" statusCodes:[NSIndexSet indexSetWithIndex:200]];
2 голосов
/ 07 ноября 2011

Чтобы создать CLLocation, вам нужны и широта, и долгота одновременно. Более того, координаты для CLLocation (например, CLLocationCoordinate2D) не являются NSNumbers, а являются двойными числами с плавающей запятой, так что это может подорвать соответствие значения ключа при отображении таким образом, потому что числа с плавающей точкой не являются объектами.

Чаще всего люди сохраняют широту и долготу в классе как NSNumbers, а затем строят координату CLLocationCoordinate2D по требованию после того, как объект класса создан / заполнен.

То, что вы могли бы сделать, если бы вы были так склонны, - это использовать метод willMapData: делегат для отслеживания поступающих данных, чтобы вручную заполнить CLLocation ... но для меня это излишне и требует слишком много накладных расходов.


РЕДАКТИРОВАТЬ: Добавление этого, потому что комментарии не форматируют свойство кода ...

Или вы можете поместить что-то подобное в реализацию и интерфейс вашего класса объектов ...

@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;
}
...