この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
前回のふりかえり
前編では、果物の名前と写真を表示するサンプルプログラムの作成を開始し、モデルクラスの作成を進めました。
後編では、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より提供されています。