使用RestKit进行映射时出错

时间:2014-03-25 20:48:00

标签: objective-c json restkit restkit-0.20

我正在制作一个从Wordpress网站获得3个JSON的应用程序,然后将它们映射到3个不同的类:产品,位置和类别,产品和类别映射工作得很好,但是当我映射地点时,它会混合使用产品,并导致两者都出错,继承我的位置类:

@interface Location : NSObject

@property (nonatomic, retain) NSString * alias;
@property (nonatomic, retain) NSSet * street;
@property (nonatomic, retain) NSSet * number;
@property (nonatomic, retain) NSSet * state;
@property (nonatomic, retain) NSSet * city;
@property (nonatomic, retain) NSSet * zipcode;
@property (nonatomic, copy) NSSet * locationId;

@end

这是Products类:

@interface AllProducts : NSObject

@property (nonatomic, copy) NSString * name;
@property (nonatomic, copy) NSSet * locationId;
@property (nonatomic, copy) NSSet * productCategoryId;
@property (nonatomic, strong) NSMutableArray *prices;

@end

下面是Im使用的映射:

//Products Mapping
    RKObjectMapping *productsMapping = [RKObjectMapping mappingForClass:[AllProducts class]];
    [productsMapping addAttributeMappingsFromDictionary:@{
                                                      @"title": @"name",
                                                      @"custom_fields.product_0_sucursal": @"locationId",
                                                      /*@"custom_fields.tipo_de_producto": @"productType",
                                                      @"custom_fields.product_0_price": @"price",
                                                      @"custom_fields.product_0_real_id": @"realId",
                                                      @"custom_fields.product_0_size": @"size",
                                                      @"custom_fields.product_0_modificador": @"mod",
                                                      @"custom_fields.product_0_temperatura": @"temp",*/
                                                      @"categories.id": @"productCategoryId"
                                                      }];

[productsMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"custom_fields"
                                                                                toKeyPath:@"prices"
                                                                             withMapping:pricesMapping]];


RKResponseDescriptor *productsResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:productsMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"posts" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:productsResponseDescriptor];

//Locations Mapping
RKObjectMapping *locationsMapping = [RKObjectMapping mappingForClass:[Location class]];
[locationsMapping addAttributeMappingsFromDictionary:@{
                                                       @"title": @"alias",
                                                       @"custom_fields.calle": @"street",
                                                       @"custom_fields.numero": @"number",
                                                       @"custom_fields.estado": @"state",
                                                       @"custom_fields.ciudad": @"city",
                                                       @"custom_fields.codigo_postal": @"zipcode",
                                                       @"custom_fields.locationid": @"locationId"
                                                       }];

RKResponseDescriptor *locationsResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:locationsMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"posts" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:locationsResponseDescriptor];

我在AppDelegate中有映射定义,对象的调用在tableview控制器中

对于地点:

RKObjectManager* objectManager = [RKObjectManager sharedManager];


NSDictionary *parameters;

parameters = @{
               @"json" : @"get_posts",
               @"post_type" : @"locations"
               };


[objectManager getObjectsAtPath:@"" parameters:parameters success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
 {

     _locations = [mappingResult array];
     [[self tableView]reloadData];
 }
                        failure:^(RKObjectRequestOperation *operation, NSError *error){
                            [self handleFailure:operation withError:error];
                        }];

和产品:

 //Getting all the products
RKObjectManager *objectManager = [RKObjectManager sharedManager];

//Mutable array that will contain the products when a category is selected
_productByCategory = [[NSMutableArray alloc] init];

NSDictionary *parameters;

http://localhost/?json=get_posts&post_type=products

parameters = @{
               @"json" : @"get_posts",
               @"post_type" : @"products"
               };

//Getting all the products and then selecting only the products that are in the category selected
[objectManager getObjectsAtPath:@"" parameters:parameters success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
 {

     _products = [mappingResult array];
     NSArray *tempProducts = _products;
     //NSString *productToAdd;

     BOOL isDuplicate = NO;

     for(NSSet *currentProduct in tempProducts)
     {
         for(NSSet *product in _productByCategory)
         {
             if ([[currentProduct valueForKey:@"_name"] isEqualToString:[product valueForKey:@"_name"]]){
                 isDuplicate = YES;
                 break;
             }
         }

         if(!isDuplicate && [currentProduct valueForKey:@"_name"] != nil && [[currentProduct valueForKey:@"_productCategoryId" ] containsObject:category.categoryId] && [[currentProduct valueForKey:@"_locationid"] containsObject:location.locationId]){
             //productToAdd = [[NSString alloc] initWithFormat:@"%@", [currentProduct valueForKey:@"_name"]];
             [_productByCategory addObject:currentProduct];
         }
         /*if([[currentProduct valueForKey:@"_productCategoryId" ] containsObject:category.categoryId])
         {
             [_productByCategory addObject:currentProduct];
         }*/
     }
     [[self tableView]reloadData];
 }
failure:^(RKObjectRequestOperation *operation, NSError *error){
     [self handleFailure:operation withError:error];
 }];

//update view title
self.title = [category.categoryName lowercaseString];

及以下是两者的JSON:

http://localhost/?json=get_posts&post_type=locations
{
"status": "ok",
"count": 2,
"count_total": 2,
"pages": 1,
"posts": [
    {
        "id": 263,
        "type": "locations",
        "slug": "sucursal-plaza-regia",
        "url": "http://localhost/?locations=sucursal-plaza-regia",
        "status": "publish",
        "title": "Sucursal Plaza Regia",
        "title_plain": "Sucursal Plaza Regia",
        "content": "",
        "excerpt": "",
        "date": "2014-03-25 15:44:29",
        "modified": "2014-03-25 15:44:29",
        "categories": [],
        "tags": [],
        "author": {
            "id": 1,
            "slug": "arturocalvo",
            "name": "arturocalvo",
            "first_name": "",
            "last_name": "",
            "nickname": "arturocalvo",
            "url": "",
            "description": ""
        },
        "comments": [],
        "attachments": [],
        "comment_count": 0,
        "comment_status": "closed",
        "custom_fields": {
            "calle": [
                "Av. Eugenio Garza Sada"
            ],
            "numero": [
                "No. 3720 Local L-3"
            ],
            "estado": [
                "Nuevo Leon"
            ],
            "ciudad": [
                "Monterrey"
            ],
            "codigo_postal": [
                "64780"
            ],
            "locationid": [
                "3"
            ]
        }
    },
    {
        "id": 256,
        "type": "locations",
        "slug": "sucursal-plaza-404-2",
        "url": "http://localhost/?locations=sucursal-plaza-404-2",
        "status": "publish",
        "title": "Sucursal Plaza 404",
        "title_plain": "Sucursal Plaza 404",
        "content": "",
        "excerpt": "",
        "date": "2014-03-24 16:58:20",
        "modified": "2014-03-24 16:58:20",
        "categories": [],
        "tags": [],
        "author": {
            "id": 1,
            "slug": "arturocalvo",
            "name": "arturocalvo",
            "first_name": "",
            "last_name": "",
            "nickname": "arturocalvo",
            "url": "",
            "description": ""
        },
        "comments": [],
        "attachments": [],
        "comment_count": 0,
        "comment_status": "closed",
        "custom_fields": {
            "calle": [
                "Av. Gomez Morin"
            ],
            "numero": [
                "404 Local A3-5"
            ],
            "estado": [
                "Nuevo Leon"
            ],
            "ciudad": [
                "San Pedro Garza Garcia"
            ],
            "codigo_postal": [
                "66220"
            ],
            "locationid": [
                "2"
            ]
        }
    }
],
"query": {
    "ignore_sticky_posts": true,
    "post_type": "locations"
}
}

{
"status": "ok",
"count": 5,
"count_total": 5,
"pages": 1,
"posts": [
    {
        "id": 267,
        "type": "products",
        "slug": "cafe-americano-3",
        "url": "http://localhost/?products=cafe-americano-3",
        "status": "publish",
        "title": "Cafe Americano",
        "title_plain": "Cafe Americano",
        "content": "",
        "excerpt": "",
        "date": "2014-03-25 16:55:58",
        "modified": "2014-03-25 16:55:58",
        "categories": [
            {
                "id": 1,
                "slug": "coffeebar",
                "title": "Coffee Bar",
                "description": "",
                "parent": 0,
                "post_count": 3
            }
        ],
        "tags": [],
        "author": {
            "id": 1,
            "slug": "arturocalvo",
            "name": "arturocalvo",
            "first_name": "",
            "last_name": "",
            "nickname": "arturocalvo",
            "url": "",
            "description": ""
        },
        "comments": [],
        "attachments": [],
        "comment_count": 0,
        "comment_status": "closed",
        "custom_fields": {
            "tipo_de_producto": [
                "bebida"
            ],
            "tipo_de_bebida": [
                "cafe"
            ],
            "product_0_size": [
                "l"
            ],
            "product_0_price": [
                "30"
            ],
            "product_0_sucursal": [
                "2"
            ],
            "product_0_temperatura": [
                "caliente"
            ],
            "product_0_modificador": [
                "regular"
            ],
            "product_0_priceid": [
                "432"
            ],
            "product": [
                "1"
            ]
        }
    },
    {
        "id": 266,
        "type": "products",
        "slug": "cafe-americano-2",
        "url": "http://localhost/?products=cafe-americano-2",
        "status": "publish",
        "title": "Cafe Americano",
        "title_plain": "Cafe Americano",
        "content": "",
        "excerpt": "",
        "date": "2014-03-25 16:55:23",
        "modified": "2014-03-25 16:55:23",
        "categories": [
            {
                "id": 1,
                "slug": "coffeebar",
                "title": "Coffee Bar",
                "description": "",
                "parent": 0,
                "post_count": 3
            }
        ],
        "tags": [],
        "author": {
            "id": 1,
            "slug": "arturocalvo",
            "name": "arturocalvo",
            "first_name": "",
            "last_name": "",
            "nickname": "arturocalvo",
            "url": "",
            "description": ""
        },
        "comments": [],
        "attachments": [],
        "comment_count": 0,
        "comment_status": "closed",
        "custom_fields": {
            "tipo_de_producto": [
                "bebida"
            ],
            "tipo_de_bebida": [
                "cafe"
            ],
            "product_0_size": [
                "s"
            ],
            "product_0_price": [
                "25"
            ],
            "product_0_sucursal": [
                "3"
            ],
            "product_0_temperatura": [
                "caliente"
            ],
            "product_0_modificador": [
                "regular"
            ],
            "product_0_priceid": [
                "438"
            ],
            "product": [
                "1"
            ]
        }
    }

问题在于,当我只提出产品请求时,它工作正常,当我只对位置提出请求时它也可以正常工作,但是当这两个产生时,位置会尝试映射到产品类和产品尝试要映射到位置类,我得到一个错误,有人可以帮我知道我做错了吗?,提前谢谢

1 个答案:

答案 0 :(得分:0)

因为RestKit无法分辨响应之间的差异,因为两个描述符的路径模式和关键路径是相同的(所有差异都在URL查询参数中,并且RestKit不使用它们。)

因此,您需要更改请求URL(并在响应描述符上更改pathPattern:nil)。或者更改JSON(因此您有不同的密钥路径)。或者在每个请求之后删除响应描述符,并在请求之前仅重新创建适当的响应描述符。或者使用2个不同的对象管理器,每个对象管理器只有1个响应描述符。