iOS (iPhone / iPad) SDK - Использование JSON-анализатора с Twitter_ userline - PullRequest
2 голосов
/ 31 июля 2011

Хорошо, вот мой код:

(имя_приложения) 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

(имя_приложения) 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 (я знаю, что я его неправильно написал) пуст (проблема с нулем исправлена), но «allTweets» в моем AppDelegate не пуст. Есть идеи?

1 Ответ

1 голос
/ 31 июля 2011

Проверьте, чтобы убедиться, что в вашем делегате приложения свойство viewController не равно nil.Если вы неправильно подключили его в IB (я не вижу его экземпляра в делегате вашего приложения), он будет молча завершаться ошибкой при вызове setTweets.

Кроме того, если ваш контроллер представления виден и выПереустановите свойство твитов, табличное представление не обновится само.Вместо того, чтобы синтезировать свойство твитов, напишите свой собственный метод получения и установки, например, так (вы можете также использовать KVO для этой цели, если хотите)

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

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

        [tView reloadData];
    }
}

В качестве отступления вы должны иметь -tableView:numberOfRowsInSection: return [tweets count], а не фиксированное число, и нет необходимости внедрять -tableView:heightForRowAtIndexPath:, если все ваши строки имеют одинаковую высоту - вы можете просто установить свойство rowHeight в IB или в коде в табличном представлении.

Обновление

Если ваше свойство контроллера представления не заполняется, может быть проще всего загрузить и добавить его вручную в -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];
}

Есть много способов, которыми вы можете запутаться, когда начинаете новый проект.Мне нравится сначала настраивать все мои представления так, чтобы они имели отвратительный фоновый цвет, поэтому я всегда знаю, отображаются ли они на экране или нет - использование некрасивых цветов помогает гарантировать, что я не забуду изменить их позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...