JSONでTwitterデータ表示

2010/06/29

■参考サイト [iPhone] JSON Framework の使い方(準備編)

■json-frameworkのダウンロード Google Code json-framework

■実装例 このライブラリの利用法は一応3つのやり方があるが、一番手っ取り早くプロジェクトにソースコピーで利用してみる。

(1) プロジェクトを作成する (2) ClassesにダウンロードしたJSONフォルダをコピーする。 JSON

(3) JSON.hをimportする。

#import "JSON/JSON.h"

■オレのつぶやきをログに表示 iphone

- (BOOL)application:(UIApplication *)application 
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSString *urlString = @"http://twitter.com/statuses/user_timeline/yoo_yoo_yoo.json";
    NSURL *url = [NSURL URLWithString:urlString];
    NSString *jsonString = [NSString stringWithContentsOfURL:url
                                           encoding:NSUTF8StringEncoding
                                           error:nil];
    NSArray *jsonArray = [jsonString JSONValue];
    for (NSDictionary *dic in jsonArray) {
        NSLog([dic objectForKey:@"text"]);
        NSLog([dic objectForKey:@"created_at"]);
    }
    [window makeKeyAndVisible];
    return YES;
}

(1) NSURL URLWithStringでNSURLを生成 (2) NSString stringWithContentsOfURLで指定したパスとエンコーディングで文字列(JSON)を取得  これは便利!だが、URLRequestで取得するのが一般的かもしれない。 (3) NSString JSONValueで文字列(JSON)をNSArrayに変換 (4) JSONのデータ構造にあわせて表示  Twitterの場合は、第一階層のデータはNSDictionaryとして返される。

結局のところNSStringを拡張している訳ですね!

■UITableViewで表示 iphone これ、ちとハマりました。 Navigation-based Applicationでプロジェクトを作成。 -RootViewController.h

#import <UIKit/UIKit.h>
#import "JSON/JSON.h"

@interface RootViewController : UITableViewController {
    NSArray *twitterJson;
    UITableView *twitterTableView;
}

@property (nonatomic, retain) NSArray *twitterJson;
@property (nonatomic, retain) IBOutlet UITableView *twitterTableView;
@end

-RootViewController.mの一部抜粋

- (void)viewDidLoad {
    NSString *urlString = @"http://twitter.com/statuses/user_timeline/yoo_yoo_yoo.json";
    NSURL *url = [NSURL URLWithString:urlString];
    NSString *jsonString = [NSString stringWithContentsOfURL:url
                                                    encoding:NSUTF8StringEncoding
                                                       error:nil];
    
    twitterJson = [[jsonString JSONValue] retain];
    [jsonString release];
    [super viewDidLoad];
}

- (UITableViewCell *)tableView:(UITableView *)tableView 
                cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView 
                dequeueReusableCellWithIdentifier:CellIdentifier];
    
    NSUInteger row = [indexPath row];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] 
                initWithStyle:UITableViewCellStyleDefault 
                reuseIdentifier:CellIdentifier]
                autorelease];
    }
    
    NSDictionary *rowValues = [self.twitterJson objectAtIndex:row];
    cell.textLabel.text = [rowValues objectForKey:@"text"];
    return cell;
}

最初は読み込まれるものも、スクロールするとランタイムエラーで終了してしまう・・・。 色々調べたら、viewDidLoadでJSON→NSArray変換処理の際、自動的にメモリ解放されていたのが原因のようした。 以下の記述だとエラーになります。

twitterJson = [jsonString JSONValue];

うーん、.hでretainの設定してるんだけどな〜・・・ 時間があったら調べよう。

■friend_timelinesを写真付きでとりあえず、Basic認証で取得する例

- (void)viewDidLoad {
    NSString *urlString = @"http://UserID:Password@twitter.com/statuses/friends_timeline/yoo_yoo_yoo.json";
    NSURL *url = [NSURL URLWithString:urlString];
    NSString *jsonString = [NSString stringWithContentsOfURL:url
                                                    encoding:NSUTF8StringEncoding
                                                       error:nil];
    twitterJson = [[jsonString JSONValue] retain];
    [jsonString release];
    [super viewDidLoad];
}

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView 
                             dequeueReusableCellWithIdentifier:CellIdentifier];
    
    NSUInteger row = [indexPath row];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] 
                initWithStyle:UITableViewCellStyleDefault 
                reuseIdentifier:CellIdentifier]
                autorelease];
    }
    NSDictionary *rowValues = [self.twitterJson objectAtIndex:row];
    NSDictionary *userValues = [rowValues objectForKey:@"user"];
    NSString *image_url = [userValues objectForKey:@"profile_image_url"];
    NSURL *url = [NSURL URLWithString:image_url];
    NSData *data = [NSData dataWithContentsOfURL:url];
    UIImage *image = [[UIImage alloc] initWithData:data];
    cell.imageView.image = image;
    cell.textLabel.text = [rowValues objectForKey:@"text"];
    
    [image release];
    return cell;
}

ポイントは、画像の表示方法 NSData dataWithContentsOfURLでコンテンツデータを取得し、UIImage initWithDataで作成してやる。

この場合、pngじゃなくてもOKです。 あと、imageを意図的に作成してreleaseしてやらないと、メモリリークする予感です。 XcodeのInstruments