2014-01-06 283 views
2

我使用RestKit,這是我如何初始化和添加路由和描述:RestKit映射錯了對象

- (void)initRestClient 
{ 
    NSURL *baseURL = [NSURL URLWithString:kSomeBaseURL]; 
    self.manager = [RKObjectManager managerWithBaseURL:baseURL]; 
    [self.manager setRequestSerializationMIMEType:RKMIMETypeJSON]; 
    [self.manager setAcceptHeaderWithMIMEType:RKMIMETypeJSON]; 
    [self.manager addResponseDescriptorsFromArray:[RKObjectManager sharedManager].responseDescriptors]; 
    [self.manager addRequestDescriptorsFromArray:[RKObjectManager sharedManager].requestDescriptors]; 
    [self.manager.HTTPClient.operationQueue setMaxConcurrentOperationCount:5]; 
    [RKObjectManager setSharedManager:self.manager]; 

    // AFHTTPClient *client = [RKObjectManager sharedManager].HTTPClient; 

    [self initRoutes]; 
    [self initMappingObjectsAndDiscriptors]; 
} 

- (void)initRoutes 
{  
    RKRoute *bannersRoute = [RKRoute routeWithClass:[RKBanner class] pathPattern:@"Banners?categoryID=:categoryID" method:RKRequestMethodGET]; 
    bannersRoute.shouldEscapePath = YES; 
    [self.manager.router.routeSet addRoute:bannersRoute]; 

    RKRoute *branchesRoute = [RKRoute routeWithClass:[RKBranches class] pathPattern:@"Branches?city=:city&type=:type" method:RKRequestMethodGET]; 
    branchesRoute.shouldEscapePath = YES; 
    [self.manager.router.routeSet addRoute:branchesRoute]; 

    RKRoute *shortTokenRoute = [RKRoute routeWithClass:[RKShortToken class] pathPattern:@"users/login/quick/shortToken?phone=:phone&extraCode=:extraCode" method:RKRequestMethodGET]; 
    shortTokenRoute.shouldEscapePath = YES; 
    [self.manager.router.routeSet addRoute:shortTokenRoute]; 

    RKRoute *longTokenRoute = [RKRoute routeWithClass:[RKLongToken class] pathPattern:@"users/login/quick/userDetails?shortToken=:shortToken" method:RKRequestMethodGET]; 
    longTokenRoute.shouldEscapePath = YES; 
    [self.manager.router.routeSet addRoute:longTokenRoute]; 
} 

- (void)initMappingObjectsAndDiscriptors 
{ 
    RKObjectMapping *bannerMapping = [RKObjectMapping mappingForClass:[RKBanner class]]; 
    [bannerMapping addAttributeMappingsFromDictionary:[RKBanner getAttributes]]; 
    RKResponseDescriptor *bannerDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:bannerMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"Banners" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 

    RKObjectMapping *branchesMapping = [RKObjectMapping mappingForClass:[RKBranches class]]; 
    [branchesMapping addAttributeMappingsFromDictionary:[RKBranches getAttributes]]; 
    RKResponseDescriptor *branchesDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:branchesMapping method:RKRequestMethodGET pathPattern:nil keyPath:@"Branches" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 

    RKObjectMapping *shortTokenMapping = [RKObjectMapping mappingForClass:[RKShortToken class]]; 
    [shortTokenMapping addAttributeMappingsFromDictionary:[RKShortToken getAttributes]]; 
    RKResponseDescriptor *shortTokenDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:shortTokenMapping method:RKRequestMethodGET pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 

    RKObjectMapping *longTokenMapping = [RKObjectMapping mappingForClass:[RKLongToken class]]; 
    [longTokenMapping addAttributeMappingsFromDictionary:[RKLongToken getAttributes]]; 
    // longTokenMapping.setDefaultValueForMissingAttributes = YES; 
    // longTokenMapping.setNilForMissingRelationships = YES; 
    RKResponseDescriptor *longTokenDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:longTokenMapping method:RKRequestMethodGET pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 

    [self.manager addResponseDescriptorsFromArray:@[bannerDescriptor, branchesDescriptor, shortTokenDescriptor, longTokenDescriptor]]; 

} 

這是班中的每一個是如何構建:

@interface RKBanner : NSObject 
@property (strong, nonatomic) NSNumber *idNum; 
@property (strong, nonatomic) NSString *name; 
@property (strong, nonatomic) NSString *addressURL; 
@property (strong, nonatomic) NSString *bannerPosition; 
@property (strong, nonatomic) NSString *imageALT; 
@property (strong, nonatomic) NSNumber *imageHeight; 
@property (strong, nonatomic) NSString *imageURL; 
@property (strong, nonatomic) NSNumber *imageWidth; 
@property (strong, nonatomic) NSString *subtitle; 
@property (strong, nonatomic) NSString *targetURL; 
@property (strong, nonatomic) NSString *textURL; 
@property (strong, nonatomic) NSString *title; 
+ (NSDictionary*)getAttributes; 
@end 

@implementation RKBanner 
+ (NSDictionary*)getAttributes 
{ 
    return [NSDictionary dictionaryWithObjects:@[@"idNum", @"name", @"addressURL", @"bannerPosition", @"imageALT", @"imageHeight", 
               @"imageURL", @"imageWidth", @"subtitle", @"targetURL", @"textURL", @"title"] 
             forKeys:@[@"ID", @"Name", @"AddressURL", @"BannerPosition", @"ImageALT", @"ImageHeight", 
               @"ImageURL", @"ImageWidth", @"SubTitle", @"TargetURL", @"TextURL", @"Title"]]; 
} 
@end 

@interface RKBranches : NSObject 
@property (strong, nonatomic) NSNumber *idNum; 
@property (strong, nonatomic) NSString *branchTitle; 
@property (strong, nonatomic) NSString *address; 
@property (strong, nonatomic) NSNumber *branchType; 
@property (strong, nonatomic) NSString *city; 
@property (strong, nonatomic) NSString *fax; 
@property (assign, nonatomic) BOOL isCanOrder; 
@property (assign, nonatomic) BOOL isMe; 
@property (strong, nonatomic) NSString *openHours; 
@property (strong, nonatomic) NSString *orderCode; 
@property (strong, nonatomic) NSString *phone; 
@property (strong, nonatomic) NSString *remarks; 
+ (NSDictionary*)getAttributes; 
@end 

@implementation RKBranches 
+ (NSDictionary*)getAttributes 
{ 
    return [NSDictionary dictionaryWithObjects:@[@"idNum", @"branchTitle", @"address", @"branchType", @"city", @"fax", 
               @"isCanOrder", @"isMe", @"openHours", @"orderCode", @"phone", @"remarks"] 
             forKeys:@[@"ID", @"Name", @"Address", @"BranchType", @"City", @"Fax", 
               @"IsCanOrder", @"IsMe", @"OpenHours", @"OrderCode", @"Phone", @"Remarks"]]; 
} 
@end 

@interface RKShortToken : NSObject 
@property (strong, nonatomic) NSString *responseError; 
@property (strong, nonatomic) NSString *shortToken; 
+ (NSDictionary*)getAttributes; 
@end 

@implementation RKShortToken 
+ (NSDictionary*)getAttributes 
{ 
    return [NSDictionary dictionaryWithObjects:@[@"responseError", @"shortToken"] 
             forKeys:@[@"responseError", @"shortToken"]]; 
} 
@end 

@interface RKLongToken : NSObject 
@property (strong, nonatomic) NSString *responseError; 
@property (strong, nonatomic) NSString *responseMessage; 
@property (strong, nonatomic) NSString *responseHttpCode; 
@property (strong, nonatomic) NSString *responseUserMessage; 
@property (strong, nonatomic) NSString *abroadInd; 
@property (strong, nonatomic) NSString *accountType; 
@property (strong, nonatomic) NSString *customerID; 
@property (strong, nonatomic) NSString *longToken; 
+ (NSDictionary*)getAttributes; 
@end 

@implementation RKLongToken 
+ (NSDictionary*)getAttributes 
{ 
    return [NSDictionary dictionaryWithObjects:@[@"responseError", @"responseMessage", @"responseHttpCode", @"responseUserMessage", 
               @"abroadInd", @"accountType", @"customerID", @"longToken"] 
             forKeys:@[@"responseError", @"responseError.DeveloperMessage", @"responseError.HttpCode", @"responseError.UserMessage", 
               @"abroadInd", @"accountType", @"customerId", @"longToken"]]; 
} 
@end 

比當我嘗試調用RKShortToken,我得到了很好的迴應,但我得到的對象是RKLongToken:

- (void)quickLoginWithTelephone:(NSString*)telephone extraCode:(NSString *)extraCode completionBlock:(quickLoginExtraCodeCompletionBlock)success 
{ 
    NSDictionary *params = @{ @"phone" : telephone, @"extraCode" : extraCode }; 
    [[RKObjectManager sharedManager] getObjectsAtPath:@"users/login/quick/shortToken?" 
              parameters:params 
               success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { 
                NSLog(@"%@", operation.HTTPRequestOperation.responseString); 
                NSLog(@"%@", mappingResult.array); 
                success(YES); 
               } failure:^(RKObjectRequestOperation *operation, NSError *error) { 
                NSLog(@"Error occurred."); 
               }]; 
} 

這裏是個e日誌:

2014-01-06 15:46:01.428 Online[8796:60b] I restkit.network:RKObjectRequestOperation.m:180 GET 'http://10.174.10.35/service/service.svc/users/login/quick/shortToken?&extraCode=null&phone=0505717596' 

2014-01-06 15:50:03.999 Online[8796:60b] {"responseError":null,"shortToken":"I55933325601458654742"} 
2014-01-06 15:46:01.577 Online[8796:60b] (
    "<RKLongToken: 0x14dd3a50>" 
) 

2014-01-06 15:46:04.490 Online[8796:1403] I restkit.network:RKObjectRequestOperation.m:250 GET 'http://10.174.10.35/service/service.svc/users/login/quick/shortToken?&extraCode=null&phone=0505717596' (200 OK/1 objects) [request=3.0587s mapping=0.0030s total=3.1129s] 

這裏似乎是什麼問題?

UPDATE:

我已經添加pathPattern的描述符@Wain告訴我,但現在我發現了一個錯誤。它看起來像這樣:

"No mappable object representations were found at the key paths searched." 

NSLocalizedFailureReason=The mapping operation was unable to find any nested object representations at the key paths searched: Banners, Branches, BranchTypes, Cities, MenuList 
The representation inputted to the mapper was found to contain nested object representations at the following key paths: responseError, shortToken 
This likely indicates that you have misconfigured the key paths for your mappings., NSLocalizedDescription=No mappable object representations were found at the key paths searched., keyPath=null}` 

回答

0

做正確的方法是先初始化RestKit客戶端:

NSURL *baseURL = [NSURL URLWithString:kServiceBaseURL]; 
self.manager = [RKObjectManager managerWithBaseURL:baseURL]; 
[self.manager setRequestSerializationMIMEType:RKMIMETypeJSON]; 
[self.manager setAcceptHeaderWithMIMEType:RKMIMETypeJSON]; 
[self.manager addResponseDescriptorsFromArray:[RKObjectManager sharedManager].responseDescriptors]; 
[self.manager addRequestDescriptorsFromArray:[RKObjectManager sharedManager].requestDescriptors]; 
[self.manager.HTTPClient.operationQueue setMaxConcurrentOperationCount:5]; 
[RKObjectManager setSharedManager:self.manager]; 

比初始化你想要的路線:

RKRoute *shortTokenRoute = [RKRoute routeWithClass:[RKShortToken class] pathPattern:@"users/login/quick/shortToken" method:RKRequestMethodGET]; 
shortTokenRoute.shouldEscapePath = YES; 
[self.manager.router.routeSet addRoute:shortTokenRoute]; 

比創建一個reponseDescriptor:

RKObjectMapping *shortTokenMapping = [RKObjectMapping mappingForClass:[RKShortToken class]]; 
[shortTokenMapping addAttributeMappingsFromDictionary:@{ @"responseError" : @"responseError", @"shortToken" : @"shortToken" }]; 
RKResponseDescriptor *shortTokenDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:shortTokenMapping 
                          method:RKRequestMethodAny 
                        pathPattern:@"users/login/quick/shortToken" 
                         keyPath:nil 
                        statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 
[[RKObjectManager sharedManager] addResponseDescriptor:shortTokenDescriptor]; 

比請求:

NSDictionary *params = @{ @"phone" : telephone, @"extraCode" : extraCode }; 
[[RKObjectManager sharedManager] getObject:[[RKShortToken alloc] init] 
             path:@"users/login/quick/shortToken" 
           parameters:params 
            success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { 
             NSLog(@"%@", operation.HTTPRequestOperation.responseString); 
            } failure:^(RKObjectRequestOperation *operation, NSError *error) { 
             NSLog(@"%@", error.localizedDescription); 
            }]; 

享受。

1

您的所有響應描述符具有pathPattern:nil,所以RestKit不能過濾和將適用所有這些,看看會發生什麼。因此,對於所有的JSON,您將獲得僅包含與JSON匹配的每個映射部分的多個對象。

要修復,請添加路徑模式以允許RestKit確定哪個響應描述符與您的每個請求匹配。

+0

但是我已經在RKRoute上面有pathPattern,當我在描述符中放置相同的pathPattern時,它不會返回任何內容。 –

+0

請檢查我的更新在頂部。 –

+0

這是響應描述符,需要指定路徑模式(以匹配路由)。 – Wain