iOS上的RestKit - 嵌套对象的后续API调用?

Posted

技术标签:

【中文标题】iOS上的RestKit - 嵌套对象的后续API调用?【英文标题】:RestKit on iOS - subsequent API calls for nested objects? 【发布时间】:2012-07-05 14:09:02 【问题描述】:

我正在使用 RestKit 将数据从 Foursquare API 提取到我的 iphone 应用程序中,但是在嵌套对象的后续 API 调用中遇到了问题。

具体来说:

    我调用场地搜索 API (https://developer.foursquare.com/docs/venues/search) 来检索场地列表。每个 Venue 都有一个唯一的 ID,该 ID 包含在响应中。我在 ViewController 中使用以下内容执行此操作:

    [objectManager loadObjectsAtResourcePath:[NSString stringWithFormat:@"%@?%@", [URL resourcePath], [URL query]] delegate:self]; 
    

    然后我进行 RestKit 映射等,并将场地存储在数据数组中。到目前为止一切正常。

    此时,我遍历数据数组中的场地,并且必须进行后续 API 调用以检索有关每个场地的更多详细信息。对于每个 Venue,我使用唯一 ID 并调用 Venue detail API (https://developer.foursquare.com/docs/venues/venues)。这是难倒我的部分。我正在尝试获取从第二个 API 调用返回的 Photo 对象的 NSArray。到目前为止,我已经尝试过这种变体:

    for (id venue in self.data)
        Venue *myvenue = (Venue *)venue;
        RKURL *URL = [RKURL URLWithBaseURL:[objectManager baseURL] resourcePath:[NSString stringWithFormat:@"/venues/%@", myvenue.venueid]  queryParameters:queryParams];
        [objectManager loadObjectsAtResourcePath:[NSString stringWithFormat:@"%@?%@", [URL resourcePath], [URL query]] delegate:self];
    
    

    在我的映射中:

    RKObjectMapping *photosMapping = [RKObjectMapping mappingForClass:[Photo class]];
    [photosMapping mapKeyPathsToAttributes:@"url", @"imageURL", nil];  
    [venueMapping mapRelationship:@"photos" withMapping:photosMapping];
    [objectManager.mappingProvider setMapping:photosMapping forKeyPath:@"response.photos"];  // not sure if this keypath is for the second API call
    

    我的 Venue 课程有这个:

    @property (strong, nonatomic) NSArray *photos;
    

Venue.photos 总是返回空白。有什么建议吗?

【问题讨论】:

【参考方案1】:

从您发布的代码中,您无法将响应与地点联系起来。我不确定foursquare返回的确切JSON,但您需要想出一种方法来使用具有嵌套照片对象的场地映射进行映射。如果foursquare在其响应中没有返回对原始Venue对象的引用,您可以尝试将RKObjectLoader的targetObject属性设置为Venue(代码中的myVenue)

【讨论】:

感谢 Paul,您说得对,照片回复并未与任何地方的场地相关联。我在修改映射后让它工作了,但没有使用 RKObjectLoader 的 targetObject 属性 - 我使用 willMapData 代替,将foursquare响应修改为我需要的格式。将很快添加我如何做到这一点的答案。【参考方案2】:

不确定这是否是“最好”的方法,但我最终还是成功了。 Paul de Lange 关于没有正确绘制场地和照片的评论让我走上了正确的道路。

foursquare 响应不是我的应用程序所需的格式,所以我不得不在其余的映射操作之前使用 RKObjectLoader 的 willMapData 稍微修改响应。

这是以防将来对任何人有所帮助:

- (void)objectLoader:(RKObjectLoader *)loader willMapData:(inout id *)mappableData 
    NSArray* origPhotosArray = [*mappableData valueForKeyPath:@"response.venue.photos.groups"];
    NSMutableArray* newPhotosArray =  [[NSMutableArray alloc] init];  

    // <snip> Some extra code goes here where I discarded photos I did not want....  </snip>

    // Create copies of objects in the format that I want
    NSMutableDictionary *myphoto = [[NSMutableDictionary alloc] initWithDictionary:Photo];
    NSString *venueID = [*mappableData valueForKeyPath:@"response.venue.id"];
    [myphoto setObject:venueID forKey:@"assignedVenueid"];
    [newPhotosArray addObject:myphoto];

    // Replace the new objects instead of the response objects
    [*mappableData removeObjectForKey:@"response.venue.photos.groups"];      
    [*mappableData setObject:newPhotosArray forKey:@"response.venue.photos.groups"]; 


在我的映射中:

RKManagedObjectMapping *photosMapping = [RKManagedObjectMapping mappingForClass:[Photo class] inManagedObjectStore:objectStore];
[photosMapping mapKeyPath:@"url" toAttribute:@"imageURL"];
[photosMapping mapKeyPath:@"assignedVenueid" toAttribute:@"assignedVenueid"];
[venueMapping mapRelationship:@"photos" withMapping:photosMapping];
[objectManager.mappingProvider setMapping:photosMapping forKeyPath:@"response.venue.photos.groups"]; 
[photosMapping hasOne:@"assignedVenue" withMapping:venueMapping];
[photosMapping connectRelationship:@"assignedVenue" withObjectForPrimaryKeyAttribute:@"assignedVenueid"];    

【讨论】:

以上是关于iOS上的RestKit - 嵌套对象的后续API调用?的主要内容,如果未能解决你的问题,请参考以下文章

iOS:RESTKit 与 CoreData 同步数据

RestKit RKObjectMapping .. 嵌套和一次性对象

如何递归加载RestKit中由外键标识的嵌套对象?

使用 RestKit 和 CoreData 同步修改对象的正确方法

如何使用 RestKit 加载多个不相关的对象?

iOS Restkit:如何解析嵌套路径