Skip to content

Instantly share code, notes, and snippets.

@quique123
Created November 4, 2009 01:57
Show Gist options
  • Save quique123/225696 to your computer and use it in GitHub Desktop.
Save quique123/225696 to your computer and use it in GitHub Desktop.
//
// ImageLoadingOp.h
// PersonList
//
// Created by Marcio Valenzuela on 10/20/09.
// Copyright 2009 Personal. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
extern NSString *const ImageResultKey;
extern NSString *const URLResultKey;
@interface ImageLoadingOp : NSOperation {
NSURL *imageURL;
id target;
SEL action;
}
- (id)initWithImageURL:(NSURL *)imageURL target:(id)target action:(SEL)action;
@end
//
// ImageLoadingOp.m
// PersonList
//
// Created by Marcio Valenzuela on 10/20/09.
// Copyright 2009 Personal. All rights reserved.
//
#import "ImageLoadingOp.h"
NSString *const ImageResultKey = @"image";
NSString *const URLResultKey = @"url";
@implementation ImageLoadingOp
- (id)initWithImageURL:(NSURL *)theImageURL target:(id)theTarget action:(SEL)theAction
{
self = [super init];
if (self) {
imageURL = [theImageURL copyWithZone:nil];
target = theTarget;
action = theAction;
}
NSLog(@"EXITING INITIMAGELOADINGOP");
return self;
}
- (void)dealloc
{
[imageURL release];
[super dealloc];
}
- (void)main
{
// Synchronously oad the data from the specified URL.
NSLog(@"ENTER IMAGELOADINGOP MAIN");
NSData *data = [[NSData alloc] initWithContentsOfURL:imageURL];
UIImage *image = [[UIImage alloc] initWithData:data];
NSLog(@"IN ILOP main data %@", data);
// Package it up to send back to our target.
NSDictionary *result = [NSDictionary dictionaryWithObjectsAndKeys:image, ImageResultKey, imageURL, URLResultKey, nil];
[target performSelectorOnMainThread:action withObject:result waitUntilDone:NO];
[data release];
[image release];
NSLog(@"EXITING IMAGELOADINGOP MAIN dict");
}
@end
//
// Person.h
// P3Scratch
//
// Created by Marcio Valenzuela on 10/30/09.
// Copyright 2009 Personal. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Person : NSObject {
NSString *screenName;
NSString *realName;
NSURL *imageURL;
//for later on when i get tweets rollin
NSMutableArray *statusUpdates;
NSMutableArray *timeStamps;
NSDictionary *twitterDictionary;
}
@property(nonatomic,retain)NSString *screenName;
@property(nonatomic,retain)NSString *realName;
@property(nonatomic,retain)NSURL *imageURL;
//for later on when i get tweets rollin
@property(nonatomic,retain)NSMutableArray *statusUpdates;
@property(nonatomic,retain)NSMutableArray *timeStamps;
@property(nonatomic,retain)NSDictionary *twitterDictionary;
//-(id)initWithScreenName:(NSString*)name;
//-(id)initWithScreenName:(NSString*)name RealName:(NSString*)rname;
-(id)initWithScreenName:(NSString*)name RealName:(NSString*)rname URL:(NSURL*)url;
-(id)initWithObject:(Person*)Object;
@end
//
// Person.m
// P3Scratch
//
// Created by Marcio Valenzuela on 10/30/09.
// Copyright 2009 Personal. All rights reserved.
//
#import "Person.h"
@implementation Person
@synthesize screenName;
@synthesize realName;
@synthesize imageURL;
//for later on when i get tweets rollin
@synthesize statusUpdates;
@synthesize timeStamps;
@synthesize twitterDictionary;
/*
-(id)initWithScreenName:(NSString*)name{
screenName = name;
return self;
}
-(id)initWithScreenName:(NSString*)name RealName:(NSString*)rname{
screenName = name;
realName = rname;
return self;
}
*/
-(id)initWithScreenName:(NSString*)name RealName:(NSString*)rname URL:(NSURL*)url{
screenName = name;
realName = rname;
imageURL = url;
return self;
}
-(id)initWithObject:(Person*)Object{
screenName = [Object.screenName copyWithZone:nil];
realName = [Object.realName copyWithZone:nil];
imageURL = [Object.imageURL copyWithZone:nil];
return self;
}
@end
//
// PersonListViewController.h
// P3Scratch
//
// Created by Marcio Valenzuela on 10/30/09.
// Copyright 2009 Personal. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "Person.h"
#import "TwitterHelper.h"
@interface PersonListViewController : UITableViewController {
NSMutableArray *persons;
NSString *filePath;
NSMutableDictionary *cachedImages;
NSOperationQueue *operationQueue;
UIActivityIndicatorView *spinner;
UILabel *loadingLabel;
Person *twit;
// Person *personToDisplay;
}
@property(nonatomic,retain) NSMutableArray *persons;
@property(nonatomic,retain) NSString *filePath;
@property(nonatomic,retain) NSMutableDictionary *cachedImages;
@property(nonatomic,retain) Person *twit;
//@property(nonatomic,retain) Person *personToDisplay;
-(id)initWithStyle:(UITableViewStyle)style;
-(UIImage*)cachedImageForURL:(NSURL*)url;//to cache images
-(void)showLoadingIndicators;//show spinner
-(void)hideLoadingIndicators;//hide spinner
-(void)beginLoadingTwitterData;//create operation queue and load twitterdata //call spinners
-(void)synchronousLoadTwitterData;//could be the same as beginLoadingTwitterData
-(void)didFinishLoadingTwitterDataWithResults;//to return fetched data
-(void)makeNewTweet;//to make new tweets :)
@end
//
// PersonListViewController.m
// P3Scratch
//
// Created by Marcio Valenzuela on 10/30/09.
// Copyright 2009 Personal. All rights reserved.
//
#import "PersonListViewController.h"
#import "ImageLoadingOp.h"
NSString *const LoadingPlacedholder = @"Loading";
@implementation PersonListViewController
@synthesize persons;
@synthesize cachedImages;
@synthesize twit;
@synthesize filePath;
//@synthesize personToDisplay;
#pragma mark ----------------------------------------------------------------------
#pragma mark initAllocMethods
-(id)initWithStyle:(UITableViewStyle)style{
self = [super initWithStyle:style];
self.title = @"People List";
operationQueue = [[NSOperationQueue alloc]init];
[operationQueue setMaxConcurrentOperationCount:1];
return self;
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self showLoadingIndicators];
[self beginLoadingTwitterData];
}
-(void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *tweetButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:@selector(makeNewTweet)];
self.navigationItem.rightBarButtonItem = tweetButton;
[tweetButton release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
[cachedImages removeAllObjects];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[persons release];
[cachedImages release];
[operationQueue release];
[super dealloc];
}
#pragma mark -----------------------------------------------------------------------
#pragma mark Loading Progress UI
- (void)showLoadingIndicators{
if (!spinner) {
spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
loadingLabel = [[UILabel alloc] initWithFrame:CGRectZero];
loadingLabel.font = [UIFont systemFontOfSize:20];
loadingLabel.textColor = [UIColor grayColor];
loadingLabel.text = @"Loading...";
[loadingLabel sizeToFit];
static CGFloat bufferWidth = 8.0;
CGFloat totalWidth = spinner.frame.size.width + bufferWidth + loadingLabel.frame.size.width;
CGRect spinnerFrame = spinner.frame;
spinnerFrame.origin.x = (self.tableView.bounds.size.width - totalWidth) / 2.0;
spinnerFrame.origin.y = (self.tableView.bounds.size.height - spinnerFrame.size.height) / 2.0;
spinner.frame = spinnerFrame;
[self.tableView addSubview:spinner];
CGRect labelFrame = loadingLabel.frame;
labelFrame.origin.x = (self.tableView.bounds.size.width - totalWidth) / 2.0 + spinnerFrame.size.width + bufferWidth;
labelFrame.origin.y = (self.tableView.bounds.size.height - labelFrame.size.height) / 2.0;
loadingLabel.frame = labelFrame;
[self.tableView addSubview:loadingLabel];
}
}
- (void)hideLoadingIndicators{
if (spinner) {
[spinner stopAnimating];
[spinner removeFromSuperview];
[spinner release];
spinner = nil;
[loadingLabel removeFromSuperview];
[loadingLabel release];
loadingLabel = nil;
}
}
#pragma mark -----------------------------------------------------------------------
#pragma mark Twitter Data Loading OPERATIONQUEUE #1 : LOAD TWITTER DATA
-(void)beginLoadingTwitterData{
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(synchronousLoadTwitterData) object:nil];
[operationQueue addOperation:operation];
[operation release];
}
-(void)synchronousLoadTwitterData{
// GET PLIST FILE INFO
filePath = [[NSBundle mainBundle] pathForResource:@"TwitterUsers" ofType:@"plist"];
if (filePath)
{
// CREATE TWITTERIDS ARRAY FROM PLIST FILE PATH
NSArray *twitterIds = [NSArray arrayWithContentsOfFile:filePath];
if (twitterIds != nil)
{
persons = [[NSMutableArray alloc] init];
for (int count=0; count<[twitterIds count]; count++)
{
// now get information from twitter
NSDictionary *dict = [[NSDictionary alloc] initWithDictionary:[TwitterHelper fetchInfoForUsername:[twitterIds objectAtIndex:count]]];
//CREATE INSTANCES BY INITTING THEM WITH THESE VALUES VIA THE PERSON CLASS CALL
twit =[[Person alloc] initWithScreenName:[dict objectForKey:@"name"] RealName:[dict objectForKey:@"screen_name"] URL:[NSURL URLWithString:[dict objectForKey:@"profile_image_url"]]];
//NSLog(@"%@", twit.imageURL);
//ADD INSTANCES TO AN ARRAY & RELEASE THE CLASS OBJECT & THEN RETURN TO MAINTHREAD...
[persons addObject:twit];
[twit release];
}
}
}
[self performSelectorOnMainThread:@selector(didFinishLoadingTwitterDataWithResults) withObject:nil waitUntilDone:NO];
}
-(void)didFinishLoadingTwitterDataWithResults{
[self hideLoadingIndicators];
[self.tableView reloadData];
[self.tableView flashScrollIndicators]; // I guess this is only if you have more users that the screenful which isnt my case
}
#pragma mark -----------------------------------------------------------------------
#pragma mark Cached Image Loading
-(UIImage*)cachedImageForURL:(NSURL*)url{
id cachedObject = [cachedImages objectForKey:url];
if (cachedObject == nil)
{
//set loading placeholder in our cache dict
[cachedImages setObject:LoadingPlacedholder forKey:url];
//Create and queue a new image loading op
ImageLoadingOp *operation = [[ImageLoadingOp alloc] initWithImageURL:url target:self action:@selector(didFinishLoadingImageWithResult:)];
[operationQueue addOperation:operation];
[operation release];
} else if(![cachedObject isKindOfClass:[UIImage class]])
{
//were already loading the image, dont kick off another request
cachedObject = nil;
}
NSLog(@"EXIT CIFU");
return cachedObject;
}
-(void)didFinishLoadingImageWithResult:(NSDictionary*)result{
NSURL *url = [result objectForKey:@"url"];
UIImage *image = [result objectForKey:@"image"];
[cachedImages setObject:image forKey:url];
[self.tableView reloadData];
NSLog(@"EXIT DFLIWR");
}
#pragma mark -----------------------------------------------------------------------
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;//[persons count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSLog(@"here at CFRAIP Identifier");
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up data for cells
Person *personToDisplay = [[Person alloc] initWithObject:[persons objectAtIndex:indexPath.row]];
// Set up the cell...
NSLog(@"aft adding array to person object");
cell.textLabel.text = personToDisplay.screenName;
//[self cachedImageForURL:personToDisplay.imageURL];
[cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
[personToDisplay release];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
/*
PersonDetailViewController *detailView = [[PersonDetailViewController alloc] initWithStyle:(UITableViewStyle)UITableViewStyleGrouped];
detailView.someTwit = [persons objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailView animated:YES];
[detailView release];
*/
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 55;
}
#pragma mark -----------------------------------------------------------------------
#pragma mark makeNewTweet
-(void)makeNewTweet;{
/*
StatusComposeViewController *myModalViewController = [[StatusComposeViewController alloc] initWithNibName:@"StatusComposeViewController" bundle:nil];
//self.myModalViewController = [[StatusComposeViewController alloc] initWithNibName:NSStringFromClass([StatusComposeViewController class]) bundle:nil];
//[self.navigationController presentModalViewController:self.myModalViewController animated:YES];
NavigationController = [[UINavigationController alloc]init];
[NavigationController pushViewController:myModalViewController animated:NO];
[self presentModalViewController:NavigationController animated:YES];
[myModalViewController release];
Must add //[NavigationController release]; to dealloc for this new UINavCont...
*/
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment