2011-07-31 8 views
2

[OK]をクリックしてJSONパーサーを使用して、ここに私のコードは次のとおりです。のiOS(iPhone/iPadの)SDK - Twitterのuser_timeline

(appnameの)AppDelegate.h:

#import <UIKit/UIKit.h> 

    @class TwitterViewContoller; 

    @interface <appname>AppDelegate : NSObject <UIApplicationDelegate> { 
     UIWindow *window; 
     UITabBarController *rootController; 
     TwitterViewContoller *viewController; 
     NSMutableData *responseData; 
     NSMutableArray *tweets; 
    } 

    @property (nonatomic, retain) IBOutlet UIWindow *window; 
    @property (nonatomic, retain) IBOutlet UITabBarController *rootController; 
    @property (nonatomic, retain) IBOutlet TwitterViewContoller *viewController; 
    @property (nonatomic, retain) NSMutableArray *tweets; 

    @end 

(appnameの)AppDelegate.m:

#import "<appname>AppDelegate.h" 
    #import "TwitterViewContoller.h" 
    #import "SBJson.h" 

    @implementation <appname>AppDelegate 

    @synthesize window = _window; 
    @synthesize rootController; 
    @synthesize viewController; 
    @synthesize tweets; 

    #pragma mark - 
    #pragma mark Application lifecycle 

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
     // Override point for customization after application launch. 
     responseData = [[NSMutableData data] retain]; 
     tweets = [NSMutableArray array]; 

     NSURLRequest *request = [NSURLRequest requestWithURL: 
         [NSURL URLWithString:@"http://api.twitter.com/1/statuses/user_timeline.json?screen_name=USER_NAME_ID"]]; 

     [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
     //[window addSubview:rootController.view]; 
     //[window makeKeyAndVisible]; 
     return YES; 
    } 

    #pragma mark NSURLConnection delegate methods 
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
     [responseData setLength:0]; 
    } 

    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
     [responseData appendData:data]; 
    } 

    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    } 

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
     [connection release]; 
     NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
     [responseData release]; 

     //NSDictionary *results = [responseString JSONValue]; <---This... 

     //NSArray *allTweets = [results objectForKey:@"results"]; <--- and this was original code but it caused an exception, 

     NSArray *allTweets = [responseString JSONValue]; //<-- So I used this instead. 
     NSLog(@"THE ARRAY = %@", allTweets); //<-- THE ARRAY IS SHOWING FINE IN THE OUTPUT LOG 
     [viewController setTweets:allTweets]; 
     [self.window addSubview:rootController.view]; 
     [self.window makeKeyAndVisible]; 

    } 

    - (void)dealloc { 
     [_window release]; 
     [rootController release]; 
     [viewController release]; 
     [super dealloc]; 
    } 

    @end 

TwitterViewContoller.h:(はい、私はそれが間違って綴ら知っている - 笑)

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

    @interface TwitterViewContoller : UIViewController { 
     IBOutlet UILabel *label; 
     NSArray *tweets; 
     IBOutlet UITableView *tview; 
    } 

    @property(nonatomic, retain) IBOutlet UILabel *label; 
    @property(nonatomic, retain) NSArray *tweets; 

    @end 

TwitterViewContoller.m:

#import "TwitterViewContoller.h" 
    #import "Tweet.h" 

    @implementation TwitterViewContoller 

    @synthesize label; 
    @synthesize tweets; 

    #pragma mark - 
    #pragma mark Table view data source 

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
     // Return the number of sections. 
     return 1; 
    } 


    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
     // Return the number of rows in the section. 
     return 20; 
    } 

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
     return 80; 
    } 


    // Customize the appearance of table view cells. 
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

     static NSString *CellIdentifier = @"Cell"; 

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

     // Configure the cell... 
     NSLog(@"THE ARRAY = %@", tweets); //<--ARRAY IS NULL <-- <-- <-- 
     NSDictionary *aTweet = [tweets objectAtIndex:[indexPath row]]; 


     cell.textLabel.text = [aTweet objectForKey:@"text"]; 
     cell.textLabel.adjustsFontSizeToFitWidth = YES; 
     cell.textLabel.font = [UIFont systemFontOfSize:12]; 
     cell.textLabel.minimumFontSize = 10; 
     cell.textLabel.numberOfLines = 4; 
     cell.textLabel.lineBreakMode = UILineBreakModeWordWrap; 

     cell.detailTextLabel.text = [aTweet objectForKey:@"screen_name"]; 

     NSURL *url = [NSURL URLWithString:[aTweet objectForKey:@"profile_image_url"]]; 
     NSData *data = [NSData dataWithContentsOfURL:url]; 
     cell.imageView.image = [UIImage imageWithData:data]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     return cell; 
    } 


    #pragma mark - 
    #pragma mark Table view delegate 

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
     // Navigation logic may go here. Create and push another view controller. 
     /* 
      <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil]; 
      // ... 
      // Pass the selected object to the new view controller. 
      [self.navigationController pushViewController:detailViewController animated:YES]; 
      [detailViewController release]; 
     */ 
    } 

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 
     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
     if (self) { 
      // Custom initialization 
     } 
     return self; 
    } 

    - (void)didReceiveMemoryWarning { 
     // Releases the view if it doesn't have a superview. 
     [super didReceiveMemoryWarning]; 

     // Release any cached data, images, etc that aren't in use. 
    } 

    #pragma mark - View lifecycle 

    - (void)viewDidLoad { 
     [super viewDidLoad]; 
     // Do any additional setup after loading the view from its nib. 
     tweets = [[NSArray alloc]init]; 
    } 

    - (void)viewDidUnload { 
     [super viewDidUnload]; 
     // Release any retained subviews of the main view. 
     // e.g. self.myOutlet = nil; 
    } 

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
     // Return YES for supported orientations 
     return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
    } 

    - (void) dealloc { 
     [tweets release]; 
     [super dealloc]; 
    } 

    @end 

問題は、私のUITableViewがアップ表示されていることですが、私のつぶやきのどれもありません。私は、TwitterViewContollerの "つぶやき"配列(私はそれが間違っていることを知っている)が空である(null問題は修正されている)が、私のAppDelegateの "allTweets"は空ではないことに気づいた。何か案は?

答えて

1

アプリデリゲートでviewControllerプロパティがnilでないことを確認するテスト。 IBで誤配線した場合(私はあなたのアプリケーションデリゲートでインスタンス化されません)、setTweetsに電話すると暗黙に失敗します。

また、ビューコントローラが表示され、tweetsプロパティを再設定すると、テーブルビュー自体は更新されません。代わりにあなたのつぶやきプロパティを合成するので、(必要であれば、あなたも、この目的のためにKVOを使用することができます)

-(NSMutableArray*)tweets { 
    return [[tweets retain] autorelease]; 
} 

-(void)setTweets:(NSMutableArray*)newTweets { 
    if(newTweets != tweets) { 
     [newTweets retain]; 
     [tweets release]; 
     tweets = newTweets; 

     [tView reloadData]; 
    } 
} 

余談としてのように、あなたは-tableView:numberOfRowsInSection:リターン[tweets count]ではなく、固定を持っている必要があり、あなた自身のゲッターとセッターを書きます行がすべて同じ高さの場合は-tableView:heightForRowAtIndexPath:を実装する必要はありません.IBまたはテーブルビューのコードにrowHeightプロパティを設定するだけで済みます。

更新

あなたのビューコントローラのプロパティが読み込ま取得されていない場合は、それだけでロードし-application:didFinishLaunchingWithOptionsに手動で追加するのが最も簡単かもしれない - 私は、任意のインターフェイスの表示までの遅延のあなたの現在のアプローチを考えますウェブ要求の仕上げは概念的に問題がある。ネットワークが利用できない場合はどうなりますか?ここではいくつかのコードは次のとおりです。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    // ... omitting the first few lines 

    // let's make sure that we have the tab bar controller, at least 
    NSAssert(nil != self.rootViewController, @"tab bar controller not hooked up!"); 

    self.viewController = [[[TwitterViewContoller alloc] initWithNibName:@"TwitterViewContoller" andBundle:nil] autorelease]; 
    self.rootViewController.viewControllers = [NSArray arrayWithObject:self.viewController]; 

    // this is now the Right Way to set the root view for your app, in iOS 4.0 and later 
    self.window.rootViewController = self.rootViewController; 
    [self.window makeKeyAndVisible]; 
} 

新しいプロジェクトを開始しているとき、あなた自身を混乱させることが多くの方法があります。最初は奇妙な背景色を持つようにすべてのビューをカスタマイズするのが好きなので、画面に表示されているかどうかは常にわかります。醜い色を使用すると、後で変更するのを忘れないようにできます。

+0

'viewController'がnullになりました。 Interface Builderを使って設定する方法はわかりませんが。 MainWindow.xibを使用すると、Ctrl + Clickアプリケーションデリゲートをウィンドウに表示してIBOutletを選択できますが、TwitterViewContoller_iPhone.xibでは単純ではないようです。何か案は? –

+0

さらに、 '-tableView:cellForRowAtIndexPath'のNSLogテストはもはや呼び出されないようです(NSLog自体は重要ではありません。単に' cellForRowAtIndexPath'がもう呼び出されていないようです)。 –

+0

私はすぐに提案で私の答えを編集します。 –