[Obj-C] JSONデータをモデルクラスを介して画面に表示する(後編)
前回のふりかえり
前編では、果物の名前と写真を表示するサンプルプログラムの作成を開始し、モデルクラスの作成を進めました。
後編では、JSONデータの読み取り、モデルクラスのインスタンスを複数持つ配列の作成、そして画面表示などを進めます。
JSONファイルを用意
JSONファイルを用意しましょう。今回はシンプルに3種類の果物データを用意しています。また、画像リソースファイルとして、apple.png, orange.png, banana.png をプロジェクトに追加しています。
Fruits.json
[ { "name":"りんご", "image":"apple", }, { "name":"オレンジ", "image":"orange", }, { "name":"バナナ", "image":"banana", } ]
FruitService クラスを作成する
このクラスの役割は、以下のとおりです
- JSONからデータを読み取る
- Fruit型のデータ配列を返す
早速作っていきましょう。
ヘッダファイル
#import <Foundation/Foundation.h> @interface FruitService : NSObject - (NSArray *)readFruits; @end
NSArray型の返り値を持つ、readFruits メソッドを宣言しています。
実装ファイル
#import "FruitService.h" #import "Fruit.h" @implementation FruitService - (NSArray *)readFruits { NSString *path = [[NSBundle mainBundle] pathForResource:@"Fruits" ofType:@"json"]; NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:path]; NSData *data = [fileHandle readDataToEndOfFile]; id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; if (!]) { return nil; } NSMutableArray *fruitsArray = [NSMutableArray new]; for (NSDictionary *dic in json) { Fruit *fruit = [[Fruit alloc] initWithDictionary:dic]; [fruitsArray addObject:fruit]; } return [fruitsArray copy]; } @end
Fruits.json から読み取ったデータを、一旦 NSData型のデータとして変換します。その後、NSJSONSerialization クラスを用いてデータを オブジェクトの配列に変換しています。
そうしたオブジェクトをFruit型に変換し、複数の Fruit をまとめて配列として返しています。
StoryBoardの実装
果物の名前、画像(UIImageView)、次の果物を表示するためのボタンがあります。
ViewControllerの実装
ヘッダファイル
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @end
実装ファイル
#import "ViewController.h" #import "Fruit.h" #import "FruitService.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UILabel *nameLabel; @property (weak, nonatomic) IBOutlet UIImageView *imageView; @property (nonatomic) NSArray *fruitsArray; @property (nonatomic) NSInteger currentFruitNumber; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; FruitService *fruitsService = [FruitService new]; self.fruitsArray = [fruitsService readFruits]; [self showFruitInformation]; } - (IBAction)tapNextButton:(id)sender { if (self.currentFruitNumber < self.fruitsArray.count - 1) { self.currentFruitNumber ++; } else { self.currentFruitNumber = 0; } [self showFruitInformation]; } - (void)showFruitInformation { Fruit *fruit = self.fruitsArray[self.currentFruitNumber]; self.nameLabel.text = fruit.name; self.imageView.image = [UIImage imageNamed:fruit.image]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end [/code] <p>詳細を見ていきましょう。</p> <h4>プロパティ</h4> <p><tt>tapNextButton</tt>では、ボタンを押すごとに、<tt>currentFruitNumber</tt>(現在の表示番号)を変化させ、画面表示を更新しています。</p> <h4>showFruitInformation</h4> - (void)showFruitInformation { Fruit *fruit = self.fruitsArray[self.currentFruitNumber]; self.nameLabel.text = fruit.name; self.imageView.image = [UIImage imageNamed:fruit.image]; }
showFruitInformationでは、fruitsArray の中から、1つの Fruit を取り出しています。
さらに、Fruit のプロパティである、name(果物名)とimage(画像名)を取り出し、画面に反映させています。
実行してみる
Next ボタンをタップするごとに、表示が切り替わります。 お疲れ様でした!
クレジット
本記事中の画像はCC BY-SA 2.0より提供されています。