How to map local NSDictionary into a custom Object using RKMappingOperation?

87 Views Asked by At
RJobObject * jobObj = [RJobObject new];

RKMappingOperation *mappingOperation = [[RKMappingOperation alloc] initWithSourceObject:jobDictionary destinationObject:jobObj mapping:[RJobObject mapping]];

mappingOperation.dataSource = (id)jobObj;
[mappingOperation start];


jobDictionary structure:
NSDictionary *msg1 = @{
                       @"id" : @"dfcd",
                       @"message" : @"ndjfcdfcd"
                       };
NSDictionary *msg2 = @{
                       @"id" : @"fjvdfv",
                       @"message" : @"kjndcdovc"
                       };
NSDictionary *msg3 = @{
                       @"id" : @"fce",
                       @"message" : @"dfcdf"
                       };

NSArray *msgsArray = [NSArray arrayWithObjects:msg1, msg2,msg3, nil];

NSMutableDictionary * jobDictionary = [NSMutableDictionary dictionaryWithDictionary:@{@"id" : @"Sourabh pant",
                                                                            @"title": @"http://www.google.com"
                                                                            }];

[jobDictionary setObject:msgsArray forKey:@"messages"];

/......................................................./

RJobObject is the custom object:
@property (nonatomic) NSString * id;
@property (nonatomic) long long duration;
@property (nonatomic) NSString * title;
@property (nonatomic) NSString * image;
@property (nonatomic) NSString * secret;
@property (nonatomic) NSInteger unreadCount;
@property (nonatomic) NSArray * messages;

This creates a crash inside RRestkit, if the jobDictionary contains messages.If the messages array inside jobDictionary is empty,then the code runs fine. So to sum up the message array is not being mapped.

Stack trace 2015-11-28 15:59:22.808 Checking Rest Kit[35951:3402596] -

[RJobObject mappingOperation:targetObjectForRepresentation:withMapping:inRelationship:]: unrecognized selector sent to instance 0x79f96270
2015-11-28 16:00:48.987 Checking Rest Kit[35951:3402596] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RJobObject mappingOperation:targetObjectForRepresentation:withMapping:inRelationship:]: unrecognized selector sent to instance 0x79f96270'
*** First throw call stack:
(
    0   CoreFoundation                      0x018e3a14 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x013a2e02 objc_exception_throw + 50
    2   CoreFoundation                      0x018ecd63 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
    3   CoreFoundation                      0x0182a6bd ___forwarding___ + 1037
    4   CoreFoundation                      0x0182a28e _CF_forwarding_prep_0 + 14
    5   Checking Rest Kit                   0x00142f48 -[RKMappingOperation destinationObjectForMappingRepresentation:parentRepresentation:withMapping:inRelationship:] + 1704
    6   Checking Rest Kit                   0x00149885 __64-[RKMappingOperation mapOneToManyRelationshipWithValue:mapping:]_block_invoke + 149
    7   CoreFoundation                      0x018152e9 __53-[__NSArrayI enumerateObjectsWithOptions:usingBlock:]_block_invoke + 73
    8   CoreFoundation                      0x01815182 -[__NSArrayI enumerateObjectsWithOptions:usingBlock:] + 162
    9   CoreFoundation                      0x017ff835 -[NSArray enumerateObjectsUsingBlock:] + 53
    10  Checking Rest Kit                   0x0014920b -[RKMappingOperation mapOneToManyRelationshipWithValue:mapping:] + 2763
    11  Checking Rest Kit                   0x0014b4fb -[RKMappingOperation applyRelationshipMappings] + 6283
    12  Checking Rest Kit                   0x0014d7db -[RKMappingOperation main] + 4075
    13  Checking Rest Kit                   0x0014c7dd -[RKMappingOperation start] + 45
    14  Checking Rest Kit                   0x000ab866 -[ViewController jobObjectFromJobDictionary:] + 310
    15  Checking Rest Kit                   0x000ab6d5 -[ViewController fetchJobFromDbForId:] + 85
    16  Checking Rest Kit                   0x000ab566 -[ViewController viewDidLoad] + 918
    17  UIKit                               0x01e3b2ae -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 44
    18  UIKit                               0x01e3fdce -[UIViewController loadViewIfRequired] + 1384
    19  UIKit                               0x01e401ed -[UIViewController view] + 35
    20  UIKit                               0x01cedf94 -[UIWindow addRootViewControllerViewIfPossible] + 69
    21  UIKit                               0x01cee6b1 -[UIWindow _setHidden:forced:] + 304
    22  UIKit                               0x01ceea67 -[UIWindow _orderFrontWithoutMakingKey] + 49
    23  UIKit                               0x01d02118 -[UIWindow makeKeyAndVisible] + 80
    24  UIKit                               0x01c6a6e7 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4190
    25  UIKit                               0x01c71cd6 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1989
    26  UIKit                               0x01c96ee5 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke3218 + 68
    27  UIKit                               0x01c6e966 -[UIApplication workspaceDidEndTransaction:] + 163
    28  FrontBoardServices                  0x04c4dc76 __37-[FBSWorkspace clientEndTransaction:]_block_invoke_2 + 71
    29  FrontBoardServices                  0x04c4d74d __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 54
    30  FrontBoardServices                  0x04c6b173 -[FBSSerialQueue _performNext] + 184
    31  FrontBoardServices                  0x04c6b5aa -[FBSSerialQueue _performNextFromRunLoopSource] + 52
    32  FrontBoardServices                  0x04c6a8a6 FBSSerialQueueRunLoopSourceHandler + 33
    33  CoreFoundation                      0x017fd6ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    34  CoreFoundation                      0x017f338b __CFRunLoopDoSources0 + 523
    35  CoreFoundation                      0x017f27a8 __CFRunLoopRun + 1032
    36  CoreFoundation                      0x017f20e6 CFRunLoopRunSpecific + 470
    37  CoreFoundation                      0x017f1efb CFRunLoopRunInMode + 123
    38  UIKit                               0x01c6e206 -[UIApplication _run] + 540
    39  UIKit                               0x01c73bfa UIApplicationMain + 160
    40  Checking Rest Kit                   0x000af02a main + 138
    41  libdyld.dylib                       0x03911a21 start + 1
    42  ???                                 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

     In Rconnection.m
    - (id)destinationObjectForMappingRepresentation:(id)representation parentRepresentation:(id)parentRepresentation withMapping:(RKMapping *)mapping inRelationship:(RKRelationshipMapping *)relationshipMapping {

    /* Some Code */
    ............
    if (destinationObject == nil)
{
    NSDictionary *dictionaryRepresentation = [representation isKindOfClass:[NSDictionary class]] ? representation : @{ [NSNull null] : representation };
    RKMappingMetadata *parentMetadata = [RKMappingMetadata new];
    parentMetadata.parentObject = self.destinationObject ?: [NSNull null];
    NSArray *metadata = RKInsertInMetadataList(self.metadataList, parentMetadata, nil);
    RKMappingSourceObject *sourceObject = [[RKMappingSourceObject alloc] initWithObject:dictionaryRepresentation parentObject:parentRepresentation rootObject:self.rootSourceObject metadata:metadata];
    // Crashing Breakpoint below:
    destinationObject = [dataSource mappingOperation:self targetObjectForRepresentation:(NSDictionary *)sourceObject withMapping:concreteMapping inRelationship:relationshipMapping];
}

   .......
   /* Some code */

}

#import <Foundation/Foundation.h>
#import <RestKit/RestKit.h>


@interface RJobObject : NSObject

@property (nonatomic) NSString * id;
@property (nonatomic) long long duration;
@property (nonatomic) NSString * title;
@property (nonatomic) NSString * image;
@property (nonatomic) NSString * secret;
@property (nonatomic) NSInteger unreadCount;
@property (nonatomic) NSArray * messages;

+(RKObjectMapping *)mapping;

@end
1

There are 1 best solutions below

0
On

This line is incorrect:

mappingOperation.dataSource = (id)jobObj;

because you are giving the operation a plain data model object as a data source (and telling the compiler to like it by casting to id).

When the operation runs it needs some new instances to be created so it can map the content from the JSON dict into them, this is a job the data source is supposed to do. When the operation asks the data source you get a crash because the object you provided as the data source, jobObj, doesn't understand the request.

You need to create and set an appropriate data source that can handle this requirement.