RestKit のマッピングメモ その2
RKObjectManager を継承した ObjectManager とか作って管理すると楽かも。
#import "ObjectManager.h" #import "Stock.h" @implementation ObjectManager - (instancetype)init { NSURL *baseURL = [NSURL URLWithString:@"https://qiita.com"]; AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:baseURL]; if (client) { [client setDefaultHeader:@"Accept" value:@"application/json"]; [client registerHTTPOperationClass:[AFJSONRequestOperation class]]; [AFNetworkActivityIndicatorManager sharedManager].enabled = YES; } self = [super initWithHTTPClient:client]; if (self) { [self addStockDescriptors]; } return self; } - (void)addStockDescriptors { RKObjectMapping *responseMapping = [Stock responseMapping]; [self addResponseDescriptorsFromArray:@[ [RKResponseDescriptor responseDescriptorWithMapping:responseMapping method:RKRequestMethodGET pathPattern:@"/api/v1/users/sasata299/stocks" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)] ]]; } @end
モデルはこんな感じ。
ちなみに property の定義を忘れるとこんなエラーが出る。。
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<Stock 0x8d9e4a0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key XXX.'
#import <Foundation/Foundation.h> #import "User.h" @interface Stock : NSObject // 定義するのを忘れずに!! @property (nonatomic, copy) NSString *title; @property (nonatomic, copy) NSString *body; @property (nonatomic, copy) NSString *url; @property (nonatomic, copy) NSString *createdAt; @property (nonatomic, strong) User *user; + (RKObjectMapping *)responseMapping; @end
#import "Stock.h" @implementation Stock + (RKObjectMapping *)responseMapping { RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[self class]]; [mapping addAttributeMappingsFromDictionary:@{ @"title": @"title", @"body": @"body", @"url": @"url", @"created_at": @"createdAt" }]; RKObjectMapping *userMapping = [User responseMapping]; [mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"user" toKeyPath:@"user" withMapping:userMapping]]; return mapping; } @end
して、あとは表示したいコントローラーで以下のように呼び出す。
- (void)viewDidLoad { [super viewDidLoad]; // snip [[RKObjectManager sharedManager] getObjectsAtPath:@"/api/v1/users/sasata299/stocks" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { self.responseData = mappingResult.array; [self.tableView reloadData]; } failure:^(RKObjectRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", error); }]; }