使用 Restkit 解析数组中未命名的 JSON 数组

Posted

技术标签:

【中文标题】使用 Restkit 解析数组中未命名的 JSON 数组【英文标题】:Parsing unnamed JSON arrays within array with Restkit 【发布时间】:2014-06-09 07:49:55 【问题描述】:

我有以下 JSON 正文,其中包含数组中的十进制数数组:

(一)


"decimals":
  [
     [
        18000.00,
        18000.00
     ]
  ],
 

我创建了一个类DecimalEntity,其辅助属性为“number”(NSDecimalNumber)和递归关系“numbers”(一对多关系)。这种变体也是可能的:

(二.)

 
    "decimals":
         [
            18000.00,
            18000.00
         ],
    

如何设置DecimalEntity 的映射,以便解析上述JSON 主体?我已经为“number”设置了属性映射,它适用于(II.)但它不适用于(I.)这就是为什么我创建了DecimalEntity 和“numbers”之间的关系使用

RKPropertyMapping* decimalEntityPropertyMapping =
                              [RKRelationshipMapping relationshipMappingFromKeyPath:nil
                                                                          toKeyPath:@"numbers"
                                                                        withMapping:decimalEntityMapping];

并将此decimalEntityPropertyMapping 添加回decimalEntityMapping 以创建递归关系:

[decimalEntityMapping                        addPropertyMapping:decimalEntityPropertyMapping];

但是这个变种会因为发送到实例的**[NSNull hasPrefix:]:无法识别的选择器而崩溃**

我还尝试使用@unionOfArrays 来展平数组,但我不知道如何使用它。 [mapping addAttributeMappingsFromDictionary:@@"@unionOfArrays": @"numbers" ]; ?

谢谢你的提示。

更新:

我正在尝试以传统方式进行操作,因为我认为它应该可以工作。我改变了我的类(NSManagedObject 子类)的结构和关系:

十进制实体数组: 包含一个辅助关系 1-M 到 DecimalEntity's:"decimals"

十进制实体: 包含十进制类型的辅助属性:“数字”

DecimalEntityArray 类映射到外括号,DecimalEntity 映射到内括号:

"arrayOfArrays":
  [ >>>>> 1-M, DecimalEntityArray
     [ >>>>> 1-M, DecimalEntity
        18000.00,
        18000.00
     ]
  ],

映射设置如下所示:

// setting up the attribute mappings:
RKObjectMapping* decimalEntityMapping               = 
    [DecimalEntity mappingForStore:managedObjectStore];
RKObjectMapping* decimalEntityArrayMapping          = 
    [DecimalEntityArray mappingForStore:managedObjectStore];

// the **nil** value denotes the fact that there is no dictionary, 
// just a direct mapping to NSSet of DecimalEntity's  
RKPropertyMapping* decimalEntityPropertyMapping =
              [RKRelationshipMapping relationshipMappingFromKeyPath:nil
                                                          toKeyPath:@"decimals"
                                                        withMapping:decimalEntityMapping];

// setup the relationship between DecimalEntityArray and its DecimalEntity's 
[decimalEntityArrayMapping   addPropertyMapping:decimalEntityPropertyMapping];


// finally setup the relation between the outermost json attribute, "arrayOfArrays" 
// and DecimalEntityArray
RKPropertyMapping* decimalEntityArrayPropertyMappingPotentialWin =
    [RKRelationshipMapping relationshipMappingFromKeyPath:@"potentionalWin"
                                                toKeyPath:@"potentionalWin"
                                              withMapping:decimalEntityArrayMapping];

但此解决方案因 [NSNull hasPrefix:]: unrecognized selector sent to instance 和建议而崩溃

将 keyPath 'arrayOfArrays' 处的一对多关系值映射到 'arrayOfArrays' ... 警告:检测到包含另一个集合的集合的关系映射。这可能不是你想要的。考虑使用 KVC 集合运算符(例如 @unionOfArrays)来展平您的可映射集合。

这可能不是你想要的。但这正是我想要的。那么这种常规方式行不通?我想我离正确还有一步。

[NSNull hasPrefix:]: unrecognized selector sent to instance源自decimalEntityPropertyMapping的定义,其中KeyPath == nil。奇怪的是文档中允许使用 nil 值:

sourceKeyPath:一个键路径,从该键路径中检索要映射为关系的源对象表示中的数据。如果nil,则直接针对父对象表示进行映射。

【问题讨论】:

您是否可以控制源 JSON?您是否考虑过使用动态映射? 谢谢韦恩。不,我不能改变它被发送到客户端的方式。 (尽管我尽我所能推动更改,因为目前每个客户端都必须做一些诡计来解析它,但是 api 更改的机会真的很小)。我正在考虑使用解析主机数组的代理对象,它将包含与 DecimalNumber/或包含十进制数的新类的 1-M 关系。我会检查动态映射restkit.org/api/latest/Classes/RKDynamicMapping.html 动态映射应该会有所帮助,当您找到数组数组时,可能还可以使用像 @unionOfArrays 这样的集合运算符。 我已经用我的流氓解决方案更新了这个问题。有用。有趣的是没有副作用。添加一个新的元属性@self 来指导映射引擎将未命名的json 字段直接映射到关系商店怎么样? 将您的解决方案添加为答案,以便您接受它。 @self 问题最好作为 github 问题提出。 【参考方案1】:

解决方案

我已经检查了调试器的问题(使用符号 -[NSObject doesNotRecognizeSelector:] 添加符号异常)并添加了行 if([keyPath isKindOfClass:[NSNull class]])在 RKMappingOperation.m 中返回 YES; 并且它与上面定义的映射一起工作顺利:

// Returns YES if there is a value present for at least one key path in the given collection
static BOOL RKObjectContainsValueForKeyPaths(id representation, NSArray *keyPaths)

    for (NSString *keyPath in keyPaths) 
        if([keyPath isKindOfClass:[NSNull class]]) return YES;
        if ([representation valueForKeyPath:keyPath]) return YES;
    
    return NO;

【讨论】:

以上是关于使用 Restkit 解析数组中未命名的 JSON 数组的主要内容,如果未能解决你的问题,请参考以下文章

如何将展平的对象序列化回服务器,在 RestKit 中未展平

在 RestKit 中解析空数组时出错

通过 RestKit 使用单个字符串元素列表解析 JSON

在 Objective C 中使用 RestKit 解析复杂的 JSON

RestKit 0.20 使用 nsdata 发布数组 Json

使用 RESTkit 从 JSON 映射来自 NSManagedObject 的 NSString 数组