Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/93.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Restkit:如何配置映射以发布NSManagedObject的嵌套数组_Ios_Arrays_Restkit_One To Many_Restkit 0.20 - Fatal编程技术网

Ios Restkit:如何配置映射以发布NSManagedObject的嵌套数组

Ios Restkit:如何配置映射以发布NSManagedObject的嵌套数组,ios,arrays,restkit,one-to-many,restkit-0.20,Ios,Arrays,Restkit,One To Many,Restkit 0.20,请跳过此部分以更新3 环境:iOS7.1、MagicalRecord、Restkit、Mogenerator 所需的JSON表单如下所示: {"amount":[10,20,50]} (set of TSNDecimal's in TSNTagAmountRequest) 请求涉及以下实体: @interface TSNTagAmountRequest: NSManagedObject @property (nonatomic, strong) NSSet *amount; @end 其中

请跳过此部分以更新3

环境:iOS7.1、MagicalRecord、Restkit、Mogenerator

所需的JSON表单如下所示:

{"amount":[10,20,50]}  (set of TSNDecimal's in TSNTagAmountRequest)
请求涉及以下实体:

@interface TSNTagAmountRequest: NSManagedObject
@property (nonatomic, strong) NSSet *amount;
@end
其中,金额集合为TSNDecimal的集合:

@interface TSNDecimal: NSManagedObject
@property (nonatomic, strong) NSDecimalNumber* number;
@end
名为number的十进制数是一个帮助器

TSNDecimal的RKObjectMapping:

RKEntityMapping *decimalMapping = [RKEntityMapping 
                                       mappingForEntityForName:@"TSNDecimal" 
                                          inManagedObjectStore:managedObjectStore];

// map the value in JSON directly to the helper "number"
[decimalMapping addPropertyMapping:
    [RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"number"]];
前一行代码是我希望将“amount”:[10,20,50]正确反序列化为三个TSNDecimal,分别为它们的number属性(它可以工作),并且它应该正确地从TSNDecimal集合(通过number)序列化为JSON:“amount”:[10,20..]它在解析响应时工作,但在解析请求时不工作

其余是关系映射:

RKPropertyMapping* decimalPropertyMappingAmount =
    [RKRelationshipMapping relationshipMappingFromKeyPath:@"amount"
                                                toKeyPath:@"amount"
                                              withMapping:decimalMapping];
    RKObjectMapping* decimalMappingInverse        = [(RKEntityMapping*)decimalMapping inverseMapping];

    RKPropertyMapping* decimalPropertyMappingAmountInverse =
                  [RKRelationshipMapping relationshipMappingFromKeyPath:@"amount"
                                                              toKeyPath:@"amount"
                                                   withMapping:decimalMappingInverse];

    [tagAmountRequestMapping addPropertyMapping:decimalPropertyMappingAmountInverse];


requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:tagAmountRequestMapping
                                                          objectClass:[TSNTagAmountRequest class]
                                                          rootKeyPath:nil
                                                               method:RKRequestMethodPOST];
[_rkManager addRequestDescriptor:requestDescriptor];
(我还尝试了从KeyPath:@“amount.number”到TokePath:@“amount”,但由于向KVC([self.object valueForKey:key])传递了不正确的路径,因此引发了异常。)

最后,我定义了TSNTagAmountRequest和TSNDecimal之间的关系: TagaMonterRequestMapping=[RKObjectMapping requestMapping]; [TagaMonetRequestMapping addPropertyMapping:decimalPropertyMappingAmount]

并将描述符添加到RK管理器:

requestDescriptor = [RKRequestDescriptor 
            requestDescriptorWithMapping:tagAmountRequestMapping
                             objectClass:[TSNTagAmountRequest class]
                             rootKeyPath:nil
                                  method:RKRequestMethodPOST];

[_rkManager addRequestDescriptor:requestDescriptor];
问题是,NSJSONSerialization数据中出现异常,JSONObject:optionserror:显然是因为TSNDecimal没有从TSNDecimal.number转换为NSJSONSerialization理解的NSDecimalNumber

例外情况: JSON写入(TSNDecimal)中的类型无效。因为RKNSJSONSerialization中的dataFromObject中的数据包含由RKObjectMappingOperationDataSource(非RKManagedObjectMappingOperationDataSource)创建的TSNDecimal对象

执行其任务并将“number”转换回nil(即,转换为集合中的未命名项),但它不以这种方式工作。这是有道理的,但如果我想编写JSON正文,使用[RKResponseDescriptor ResponseDescriptor WithMapping:从响应进行解析会让我感到困惑

[decimalMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"number"]];
RKPropertyMapping* decimalPropertyMappingAmount =
    [RKRelationshipMapping relationshipMappingFromKeyPath:@"amount"
                                                toKeyPath:@"amount"
                                              withMapping:decimalMapping];
为什么不请求呢

我看到的问题是CoreData:错误:未能调用NSManagedObject类“TSNDecimal”上的指定初始值设定项

核心数据对象初始化为

TSNTagAmountRequest* request = [TSNTagAmountRequest requestWithModel:self];    


TSNDecimal* decimalEntity = nil;

for(NSDecimalNumber* number in amount) {

    decimalEntity = [TSNDecimal MR_createEntity];
    decimalEntity.number = number;
    [request addAmountObject:decimalEntity];
}
以下是日志:

    D restkit.object_mapping:RKMappingOperation.m:860 Starting mapping operation...
    T restkit.object_mapping:RKMappingOperation.m:861 Performing mapping operation: <RKMappingOperation 0x9681ca0> for '__NSDictionaryM' object. Mapping values from object <TSNTagAmountRequest: 0xf7b8c90> (entity: TSNTagAmountRequest; id: 0xf784700 <x-coredata:///TSNTagAmountRequest/tB2DF8887-7E6C-420F-998A-D250751E5CED164> ; data: {
                                                                                                                                                                                                              amount =     (
                                                                                                                                                                                                                            "0x9664220 <x-coredata:///TSNDecimal/tB2DF8887-7E6C-420F-998A-D250751E5CED165>",
                                                                                                                                                                                                                            "0x9616390 <x-coredata:///TSNDecimal/tB2DF8887-7E6C-420F-998A-D250751E5CED166>"
                                                                                                                                                                                                                            );
                                                                                                                                                                                                              }) ((null)) to object {
    } with object mapping (null)
    D restkit.object_mapping:RKMappingOperation.m:641 Mapping one to many relationship value at keyPath 'amount' to 'amount'
    CoreData: error: Failed to call designated initializer on NSManagedObject class 'TSNDecimal'
    T restkit.object_mapping:RKMappingOperation.m:542 Performing nested object mapping using mapping <RKRelationshipMapping: 0x95a0df0 amount => amount> for data: <TSNDecimal: 0x9652900> (entity: TSNDecimal; id: 0x9664220 <x-coredata:///TSNDecimal/tB2DF8887-7E6C-420F-998A-D250751E5CED165> ; data: {
                                                                                                                                                                                            number = 5;
                                                                                                                                                                                            })
    D restkit.object_mapping:RKMappingOperation.m:860 Starting mapping operation...
    T restkit.object_mapping:RKMappingOperation.m:861 Performing mapping operation: <RKMappingOperation 0x96b3d60> for 'TSNDecimal' object. Mapping values from object <TSNDecimal: 0x9652900> (entity: TSNDecimal; id: 0x9664220 <x-coredata:///TSNDecimal/tB2DF8887-7E6C-420F-998A-D250751E5CED165> ; data: {
                                                                                                                                                                                                number = 5;
                                                                                                                                                                                                }) ({
        mapping =     {
            collectionIndex = 3221208359;
        };
    }) to object <TSNDecimal: 0x96b2880> (entity: (null); id: (null) ; data: {
    }) with object mapping (null)
    T restkit.object_mapping:RKMappingOperation.m:439 Found transformable value at keyPath '(null)'. Transforming from class 'TSNDecimal' to 'NSDecimalNumber'
    E restkit.object_mapping:RKMappingOperation.m:441 Failed transformation of value at keyPath '(null)' to representation of type 'NSDecimalNumber': Error Domain=org.restkit.RKValueTransformers.ErrorDomain Code=3002 "Failed transformation of value '<TSNDecimal: 0x9652900> (entity: TSNDecimal; id: 0x9664220 <x-coredata:///TSNDecimal/tB2DF8887-7E6C-420F-998A-D250751E5CED165> ; data: {
    number = 5;
    }) ({
        mapping =     {
            collectionIndex = 3221208359;
        };
    })' to NSDecimalNumber: none of the 2 value transformers consulted were successful." UserInfo=0x96bd900 {detailedErrors=(
    "Error Domain=org.restkit.RKValueTransformers.ErrorDomain Code=3002 \"The given value is not already an instance of 'NSDecimalNumber'\" UserInfo=0x96bd630 {NSLocalizedDescription=The given value is not already an instance of 'NSDecimalNumber'}",
    "Error Domain=org.restkit.RKValueTransformers.ErrorDomain Code=3000 \"Expected an `inputValue` of type `NSNull`, but got a `TSNDecimal`.\" UserInfo=0x96bd720 {NSLocalizedDescription=Expected an `inputValue` of type `NSNull`, but got a `TSNDecimal`.}"
    ), NSLocalizedDescription=Failed transformation of value '<TSNDecimal: 0x9652900> (entity: TSNDecimal; id: 0x9664220 <x-coredata:///TSNDecimal/tB2DF8887-7E6C-420F-998A-D250751E5CED165> ; data: {
    number = 5;
    }) ({
        mapping =     {
            collectionIndex = 3221208359;
        };
    })' to NSDecimalNumber: none of the 2 value transformers consulted were successful.}
    T restkit.object_mapping:RKMappingOperation.m:519 Did not find mappable attribute value keyPath '(null)'
    D restkit.object_mapping:RKMappingOperation.m:905 Mapping operation did not find any mappable values for the attribute and relationship mappings in the given object representation
    D restkit.object_mapping:RKMappingOperation.m:927 Failed mapping operation: No mappable values found for any of the attributes or relationship mappings
    W restkit.object_mapping:RKMappingOperation.m:553 WARNING: Failed mapping nested object: No mappable values found for any of the attributes or relationship mappings

使用错误的构造函数new(这就是为什么我在日志中看到coredata错误:coredata:error:未能调用NSManagedObject类上指定的初始值设定项)的原因。self.dataSource调用错误的映射操作:targetObjectForRepresentation:因为它是非托管对象的数据源(RKObjectMappingOperationDataSource)。它应该是RKManagedObjectMappingOperationDataSource

我猜这可能与RKObjectMapping v.RKEntityMapping问题有关。但当我将RKEntityMapping用于TSNTagAmountRequest时:

tagAmountRequestMapping = [RKEntityMapping mappingForEntityForName:[TSNTagAmountRequest class] inManagedObjectStore:managedObjectStore]; 
然后我得到了错误:*由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“
RKRequestDescriptor
对象必须使用其目标类为
NSMutableDictionary
、获得了“TSNTagAmountRequest”(请参见
[RKObjectMapping requestMapping]
)的映射进行初始化”**

更新2 我更改了实现,使其使用反向映射:

RKPropertyMapping* decimalPropertyMappingAmount =
    [RKRelationshipMapping relationshipMappingFromKeyPath:@"amount"
                                                toKeyPath:@"amount"
                                              withMapping:decimalMapping];
    RKObjectMapping* decimalMappingInverse        = [(RKEntityMapping*)decimalMapping inverseMapping];

    RKPropertyMapping* decimalPropertyMappingAmountInverse =
                  [RKRelationshipMapping relationshipMappingFromKeyPath:@"amount"
                                                              toKeyPath:@"amount"
                                                   withMapping:decimalMappingInverse];

    [tagAmountRequestMapping addPropertyMapping:decimalPropertyMappingAmountInverse];


requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:tagAmountRequestMapping
                                                          objectClass:[TSNTagAmountRequest class]
                                                          rootKeyPath:nil
                                                               method:RKRequestMethodPOST];
[_rkManager addRequestDescriptor:requestDescriptor];
映射操作结束时输出异常JSON字典中的键无效(非字符串):

 (
 {
     5 =         {
     };
 },
 {
     100 =         {
     };
 }
 )
和日志:

D restkit.object_mapping:RKMappingOperation.m:860 Starting mapping operation...
T restkit.object_mapping:RKMappingOperation.m:861 Performing mapping operation: <RKMappingOperation 0xf844d50> for '__NSDictionaryM' object. Mapping values from object <TSNTicketAmountApiRequest: 0xf80e9b0> (entity: TSNTicketAmountApiRequest; id: 0xf86bbe0 <x-coredata:///TSNTicketAmountApiRequest/t5BFB6379-F8EB-4367-A53B-E1B3C531A34F66> ; data: {
                                                                                                                                                                                                                                                                   amount =     (
                                                                                                                                                                                                                                                                                 "0xf8c3b30 <x-coredata:///TSNDecimalApiTO/t5BFB6379-F8EB-4367-A53B-E1B3C531A34F67>",
                                                                                                                                                                                                                                                                                 "0xf80c370 <x-coredata:///TSNDecimalApiTO/t5BFB6379-F8EB-4367-A53B-E1B3C531A34F68>"
                                                                                                                                                                                                                                                                                 );

                                                                                                                                                                                                                                                                   }) ((null)) to object {
} with object mapping (null)
T restkit.object_mapping:RKMappingOperation.m:454 Mapping attribute value keyPath 'token' to 'token'
T restkit.object_mapping:RKMappingOperation.m:470 Mapped attribute value from keyPath 'token' to 'token'. Value: SXppH1ajA9OspKHkQ6Uwi7dD7AoYVP7J:api
T restkit.object_mapping:RKMappingOperation.m:454 Mapping attribute value keyPath 'bonification' to 'bonification'
T restkit.object_mapping:RKMappingOperation.m:470 Mapped attribute value from keyPath 'bonification' to 'bonification'. Value: 1
D restkit.network:RKObjectParameterization.m:129 Serialized NSDecimalNumber value at keyPath to __NSCFString (1)
T restkit.object_mapping:RKMappingOperation.m:454 Mapping attribute value keyPath 'isNetCurrency' to 'isNetCurrency'
T restkit.object_mapping:RKMappingOperation.m:470 Mapped attribute value from keyPath 'isNetCurrency' to 'isNetCurrency'. Value: 0
D restkit.network:RKObjectParameterization.m:129 Serialized __NSCFNumber value at keyPath to __NSCFBoolean (0)
D restkit.object_mapping:RKMappingOperation.m:641 Mapping one to many relationship value at keyPath 'amount' to 'amount'
T restkit.object_mapping:RKMappingOperation.m:542 Performing nested object mapping using mapping <RKRelationshipMapping: 0xf87bf40 amount => amount> for data: <TSNDecimalApiTO: 0xf8f0a60> (entity: TSNDecimalApiTO; id: 0xf8c3b30 <x-coredata:///TSNDecimalApiTO/t5BFB6379-F8EB-4367-A53B-E1B3C531A34F67> ; data: {
                                                                                                                                                                                                                                                number = 5;
                                                                                                                                                                                                                                                })
D restkit.object_mapping:RKMappingOperation.m:860 Starting mapping operation...
T restkit.object_mapping:RKMappingOperation.m:861 Performing mapping operation: <RKMappingOperation 0x93779f0> for '__NSDictionaryM' object. Mapping values from object <TSNDecimalApiTO: 0xf8f0a60> (entity: TSNDecimalApiTO; id: 0xf8c3b30 <x-coredata:///TSNDecimalApiTO/t5BFB6379-F8EB-4367-A53B-E1B3C531A34F67> ; data: {
                                                                                                                                                                                                                                                         number = 5;
                                                                                                                                                                                                                                                         }) ({
    mapping =     {
        collectionIndex = 3221208359;
    };
}) to object {
} with object mapping (null)
 T restkit.object_mapping:RKMappingOperation.m:439 Found transformable value at keyPath 'number'. Transforming from class 'NSDecimalNumber' to 'NSMutableDictionary'
 T restkit.object_mapping:RKMappingOperation.m:454 Mapping attribute value keyPath 'number' to '(null)'
 T restkit.object_mapping:RKMappingOperation.m:470 Mapped attribute value from keyPath 'number' to '(null)'. Value: {
    5 =     {
    };
}
 D restkit.object_mapping:RKMappingOperation.m:929 Finished mapping operation successfully...
 T restkit.object_mapping:RKMappingOperation.m:542 Performing nested object mapping using mapping <RKRelationshipMapping: 0xf87bf40 amount => amount> for data: <TSNDecimalApiTO: 0xf8f0ea0> (entity: TSNDecimalApiTO; id: 0xf80c370 <x-coredata:///TSNDecimalApiTO/t5BFB6379-F8EB-4367-A53B-E1B3C531A34F68> ; data: {
                                                                                                                                                                                                                                                number = 100;
                                                                                                                                                                                                                                                })
 D restkit.object_mapping:RKMappingOperation.m:860 Starting mapping operation...
 T restkit.object_mapping:RKMappingOperation.m:861 Performing mapping operation: <RKMappingOperation 0x9311160> for '__NSDictionaryM' object. Mapping values from object <TSNDecimalApiTO: 0xf8f0ea0> (entity: TSNDecimalApiTO; id: 0xf80c370 <x-coredata:///TSNDecimalApiTO/t5BFB6379-F8EB-4367-A53B-E1B3C531A34F68> ; data: {
                                                                                                                                                                                                                                                         number = 100;
                                                                                                                                                                                                                                                         }) ({
    mapping =     {
        collectionIndex = 3221208359;
    };
}) to object {
} with object mapping (null)
 T restkit.object_mapping:RKMappingOperation.m:439 Found transformable value at keyPath 'number'. Transforming from class 'NSDecimalNumber' to 'NSMutableDictionary'
 T restkit.object_mapping:RKMappingOperation.m:454 Mapping attribute value keyPath 'number' to '(null)'
 T restkit.object_mapping:RKMappingOperation.m:470 Mapped attribute value from keyPath 'number' to '(null)'. Value: {

    };
}
 D restkit.object_mapping:RKMappingOperation.m:929 Finished mapping operation successfully...
 T restkit.object_mapping:RKMappingOperation.m:682 Mapped relationship object from keyPath 'amount' to 'amount'. Value: (
                                                                                                                                                                           {
                                                                                                                                                                               5 =         {
                                                                                                                                                                               };
                                                                                                                                                                           },
                                                                                                                                                                           {
                                                                                                                                                                               100 =         {
                                                                                                                                                                               };
                                                                                                                                                                           }
                                                                                                                                                                           )
更新3 这个问题归结为如何将JSON中的十进制数数组解析为NSManagedObject的NSSet(从一开始就工作),反之亦然,从NSSet解析为JSON数组(让它工作起来相当令人沮丧):

就是

TSNTagAmountRequest:{amount:[TSNDecimal, TSNDecimal, TSNDecimal, ...]}
在哪里

在哪里

    RKPropertyMapping* decimalPropertyMappingAmountInverse =
                              [RKRelationshipMapping 
                                relationshipMappingFromKeyPath:@"amount"
                                                     toKeyPath:@"amount"
                                                   withMapping:decimalMappingInverse];
 RKObjectMapping* decimalMappingInverse = [(RKEntityMapping*)decimalMapping inverseMapping];
在哪里

    RKPropertyMapping* decimalPropertyMappingAmountInverse =
                              [RKRelationshipMapping 
                                relationshipMappingFromKeyPath:@"amount"
                                                     toKeyPath:@"amount"
                                                   withMapping:decimalMappingInverse];
 RKObjectMapping* decimalMappingInverse = [(RKEntityMapping*)decimalMapping inverseMapping];
在哪里

方法+(NSData*)dataFromObject:error:from RKNSJSONSerialization无法使用包含NSDictionary:

 (
 {
     5 =         {
     };
 },
 {
     100 =         {
     };
 }
 )
在这里,我期望像[5100]这样的东西

应用程序因JSON字典中的键无效(非字符串)而崩溃

我不明白为什么[NSJSONSerialization dataWithJSONObject:object options:0 error:error];被提供给这个奇怪的字典数组而不是NSDecimalNumber数组

更新4 我已经更改了TSNTagAmountRequest和TSNDecimal之间关系映射的定义,以便TSNDecimal中的值(amount NSSet中的项)使用其属性“number”进行传播

Restkit引擎,即RKMappingOperation.m中的applyRelationshipMappings方法,能够提取数量值5100,但最终JSON的组装方式不正确:

"amount":[{},{}]
缺少值,我就快到了

更新5
为所有涉及的实体设置反向映射后,输入请求描述符,仍然输出(由映射号->nil驱动)与字典字典(而非JSON数组)的组装不正确。唯一的方法是将RKNSJSONSerialization子类化并修复结构,即将字典字典转换为与ns JSON序列化程序兼容的简单nsarray。

为什么无法使用RKRelationshipMapping创建JSON正文
-因为创建JSON是一个请求描述符操作,您只使用响应描述符。除此之外,实际上没有任何限制。我建议您展示真正的代码和真正的JSON,因为您当前的问题没有多大意义。再次感谢您。我已经更新了问题。我s试图解决它,但我自己找不到方法。仍然没有成功。将NSManagedObject的NSSet序列化到JSON数组时,一定有一些明显的问题。您似乎正在取得进展,但在请求和响应描述符用途以及零键路径映射之间存在混淆。通常,创建响应映射并描述tor,然后进行反向映射并创建请求描述符。
    RKPropertyMapping* decimalPropertyMappingAmountInverse =
                              [RKRelationshipMapping 
                                relationshipMappingFromKeyPath:@"amount"
                                                     toKeyPath:@"amount"
                                                   withMapping:decimalMappingInverse];
 RKObjectMapping* decimalMappingInverse = [(RKEntityMapping*)decimalMapping inverseMapping];
 RKObjectMapping* decimalMapping = [RKEntityMapping mappingForEntityForName:@"TSNDecimal" inManagedObjectStore:managedObjectStore];
 [mapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil          
                                                                   toKeyPath:@"number"]];


    requestDescriptor = [RKRequestDescriptor 
                      requestDescriptorWithMapping:tagAmountRequestMapping
                                       objectClass:[TSNTagAmountRequest class]
                                    rootKeyPath:TSNServiceClientRemoteRootKeyPathNotNested
                                         method:RKRequestMethodPOST];
[_rkManager addRequestDescriptor:requestDescriptor];
 (
 {
     5 =         {
     };
 },
 {
     100 =         {
     };
 }
 )
RKPropertyMapping* decimalPropertyMappingAmountInverse =
                              [RKRelationshipMapping relationshipMappingFromKeyPath:@"amount.number"
                                                                          toKeyPath:@"amount"
                                                                        withMapping:decimalApiMappingInverse];
"amount":[{},{}]