/var/log/seiji

11 Dec 2008

plistの読込み、UITableViewCellAccessory-CS193P

plistの読込み、UITableViewCellAccessory

Lecture9迄の内容を基に"Presence"アプリケーションを拡張していきます。 AssignmentPresence2の前半になります。
CS193P - Cocoa Programming | Announcements.jpg
iPhone Application Programming

今迄、作成したソースはhttp://public.me.com/seijit/iPhone/CS193Pから

今回の目標

前回のPersonListViewControllerを修正し、下のアプリケーションの内、左側を表示できるようになるのが目的です。

app-1.png

Performanceは今は考えてなくてよいとのことなので、Performanceは一切考慮していません。

xcode.png 前準備

プロジェクトへの追加

Presence2Files.zipに含まれていますTwitterAPI部分のソース、TwitterUsers.plistを追加します。TwitterUsers.plistは好きなUserに変更します。

init — Presence.png

TwitterHelperの修正

TwitterAPIはデフォルトで20件を返します。そんなに必要ないので5件にします。また、encodingが指定されてないので、指定します。その結果、下のようになります。

TwitterHelper.m
+ (NSArray *)fetchTimelineForUsername:(NSString *)username
{
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://twitter.com/statuses/user_timeline/%@.json?count=5", username]];
    NSString *string = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    return [string JSONValue];
}

xcode.png Modelの作成

起動時にTwiiterにアクセスし、必要な情報をメモリ上に格納します。その為のModelを作成します。例えば、Userの情報を格納するPersonクラス、Userのつぶやきを格納するPersonTextクラスを作成します。

Personクラス

Person.h
import <Foundation/Foundation.h>

@interface Person : NSObject {
    NSString *name;
    NSString *screenName;
    NSString *profileImageURL;
    NSMutableArray *textArray;
}
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *screenName;
@property (nonatomic, retain) NSString *profileImageURL;
@property (nonatomic, retain) NSMutableArray *textArray;

- (id)initWithPersonName:(NSString *)name;
- (id)createPerson:(NSString *)personName;
- (NSString *)description;
- (void)dealloc;

@end
Person.m
#import "Person.h"
#import "PersonText.h"
#import "TwitterHelper.h"

@implementation Person
@synthesize name, screenName, profileImageURL, textArray;

- (id)initWithPersonName:(NSString *)personName {
    if ( (self =[super init])!= nil ) {
        self = [self createPerson:personName];
    }
    return self;
}

- (id)createPerson:(NSString *)personName {
    // name
    self.screenName = personName;
    // Twitter API
    NSArray *array = [TwitterHelper fetchTimelineForUsername:personName];
    if([array count]==0) {
        return nil;
    }
    NSDictionary *user = [[array objectAtIndex:0] objectForKey:@"user"];
    self.profileImageURL = [user objectForKey:@"profile_image_url"];
    self.name = [user objectForKey:@"name"];

    self.textArray = [NSMutableArray array];
    NSDictionary *dic;
    for (dic in array) {
        NSString *text = [dic objectForKey:@"text"];
        if (text) {
            PersonText *personText = [[PersonText alloc] initWithText:text font:[UIFont systemFontOfSize:[UIFont systemFontSize]]];
            [self.textArray addObject:personText];
            [personText release];
        }
    }

    return self;
}
// 略
@end

PersonTextクラス

PersonText.h
#import <Foundation/Foundation.h>

@interface PersonText : NSObject
{
    NSString *textString;
    UIFont *font;
    CGSize size;
}
@property (nonatomic, retain)NSString *textString;
@property (nonatomic, retain)UIFont *font;
@property (nonatomic)CGSize size;

- (id)initWithText:(NSString *)text font:(UIFont *)fontObj;
- (void)dealloc;

@end
PersonText.m
#import "PersonText.h"

@implementation PersonText

@synthesize textString;
@synthesize font;
@synthesize size;

- (id)initWithText:(NSString *)txt font:(UIFont *)fontObj;{
    if ((self = [super init])!= nil) {
        self.textString = txt;
        self.font = fontObj;
        CGSize withinSize = CGSizeMake(280, 1000);
        self.size = [textString sizeWithFont:font constrainedToSize:withinSize lineBreakMode:UILineBreakModeWordWrap];
    }
    return self;
}

// 略
@end

PersonTextの方は初期化の際にwidth280pxをした際に高さを計算する為にサイズを求めています。

xcode.png PersonListViewControllerの修正

PersonListViewController.mを修正していきます。

plistの読込み

- (void)viewDidLoad {
    [super viewDidLoad];
    // load data
    self.myData = [NSMutableArray array];
    NSBundle *bundle = [NSBundle mainBundle];

    // Load plist
    NSArray *twitterUsers = [NSArray arrayWithContentsOfFile:[bundle pathForResource:@"TwitterUsers" ofType:@"plist"]];
    NSString *userName;

    for (userName in twitterUsers){
        Person *person = [[Person alloc] initWithPersonName:userName];
        if (person)
            [myData addObject:person];
        [person release];
    }
}

viewDidLoadの際にTwitterへアクセスし、Personインスタンスが要素のNSMutableArrayを作成しています。

List表示

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }

    // Set up the cell...
    int personIndex = [indexPath indexAtPosition: [indexPath length] - 1];
    Person *person = [myData objectAtIndex:personIndex];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:person.profileImageURL]];
    UIImage *image= [UIImage imageWithData:imageData];

    [cell setImage:image];
    [cell setText:person.name];
    return cell;
}

各Personインスタンスを展開しています。ここでも画像へのアクセスを行っています。

UITableViewCellAccessory

- (UITableViewCellAccessoryType)tableView:(UITableView *)table accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {
    return UITableViewCellAccessoryDisclosureIndicator;
    //return UITableViewCellAccessoryDetailDisclosureButton;
    //return UITableViewCellAccessoryCheckmark;
}

最後にCellの右側に表示されるUITableViewCellAccessoryを表示させる為にメソッドを実装しています。

これでplistから読み込んだPersonListが表示されるはずです。

今回作成したソースはhttp://public.me.com/seijit/iPhone/CS193P/Lecture9のPresence3.tar.gzです。

Comments

comments powered by Disqus