Ios RestKit映射错误的对象

Ios RestKit映射错误的对象,ios,iphone,objective-c,restkit,restkit-0.20,Ios,Iphone,Objective C,Restkit,Restkit 0.20,我正在使用RestKit,这就是我初始化它并添加路由和描述符的方式: - (void)initRestClient { NSURL *baseURL = [NSURL URLWithString:kSomeBaseURL]; self.manager = [RKObjectManager managerWithBaseURL:baseURL]; [self.manager setRequestSerializationMIMEType:RKMIMETypeJSO

我正在使用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
当我试着打电话给Rkshortoken时,我得到了很好的回应,但我得到的目标是Rkshortoken:

- (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.");
                                              }];
}
以下是日志:

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]

您的所有响应描述符都有
路径模式:nil
,因此RestKit无法进行筛选,将应用所有响应描述符并查看发生了什么。因此,对于所有JSON,您将得到多个对象,其中只包含每个映射中与JSON匹配的部分


要修复此问题,请添加路径模式,以允许RestKit确定与每个请求匹配的响应描述符。

正确的方法是首先初始化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];
而不是创建响应描述符:

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);
                                   }];

享受。

但我已经在RKRoute顶部设置了pathPattern,当我将相同的pathPattern放入描述符时,它不会返回任何内容。需要指定路径模式(以匹配路由)的是响应描述符。我将它们与路由匹配,但仍然没有任何结果。我只是不知道我做错了什么。请求很好,但returend对象始终是我添加的最后一个描述符对象。例如,我最后添加了RKLongToken,所以当我请求RKShortoken时,它会给我一个RKLongToken对象数组。。。我只是不知道发出请求的正确方式是什么。您应该为每个响应描述符获取一个与路径模式匹配的对象。为映射打开跟踪日志记录,它会为您提供处理的每个响应描述符的详细信息。我只是不知道问题出在哪里。你能私下帮我(发电子邮件或其他什么)然后我们把答案贴在这里吗?
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);
                                   }];