iOSアプリ開発のメモ置き場

ささたつがiOSアプリ開発で知ったObjective-Cのtipsなどを書いていく所存

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