Created
February 27, 2010 18:35
-
-
Save omnifroodle/316865 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <UIKit/UIKit.h> | |
@interface NewsListViewController : UITableViewController <NSFetchedResultsControllerDelegate>{ | |
NSFetchedResultsController *resultsController; | |
UIButton *sponsor; | |
} | |
@property (nonatomic, retain) NSFetchedResultsController *resultsController; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NSInteger intSort(id num1, id num2, void *context) | |
{ | |
int v1 = [num1 intValue]; | |
int v2 = [num2 intValue]; | |
if (v1 < v2) | |
return NSOrderedAscending; | |
else if (v1 > v2) | |
return NSOrderedDescending; | |
else | |
return NSOrderedSame; | |
} | |
- (int) getMaxUpdated: (NSString*)entityName key: (NSString*)keyName { | |
int result = 0; | |
[self managedObjectContext]; | |
NSFetchRequest *request = [[NSFetchRequest alloc] init]; | |
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext]; | |
[request setEntity:entity]; | |
// Specify that the request should return dictionaries. | |
[request setResultType:NSDictionaryResultType]; | |
// Create an expression for the key path. | |
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:keyName]; | |
// Create an expression to represent the max value at the key path | |
NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:" arguments:[NSArray arrayWithObject:keyPathExpression]]; | |
// Create an expression description using the minExpression and returning a date. | |
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; | |
// The name is the key that will be used in the dictionary for the return value. | |
[expressionDescription setName:[NSString stringWithFormat:@"max%@", keyName]]; | |
[expressionDescription setExpression:maxExpression]; | |
[expressionDescription setExpressionResultType:NSInteger64AttributeType]; | |
// Set the request's properties to fetch just the property represented by the expressions. | |
[request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]]; | |
// Execute the fetch. | |
NSError *error; | |
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error]; | |
if (objects == nil) { | |
// Handle the error. | |
} else { | |
if ([objects count] > 0) { | |
result = [[[objects objectAtIndex:0] valueForKey:[NSString stringWithFormat:@"max%@", keyName]] intValue]; | |
} | |
} | |
[expressionDescription release]; | |
[request release]; | |
return result; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void)applicationDidFinishLaunching:(UIApplication *)application { | |
// Override point for customization after app launch | |
[self createEditableCopyOfDatabaseIfNeeded]; | |
UIView *backgroundView = [[UIView alloc] initWithFrame: window.frame]; | |
backgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"background.png"]]; | |
[window addSubview:backgroundView]; | |
[backgroundView release]; | |
[window addSubview:tabcontroller.view]; | |
[window makeKeyAndVisible]; | |
// TODO implement fetching of most recent records | |
int maxNews = [self getMaxUpdated:@"News" key:@"updated"]; | |
int maxOccasion = [self getMaxUpdated:@"Occasion" key:@"updated"]; | |
NSLog([NSString stringWithFormat:@"max news timestamp %d", maxNews]); | |
self.lastNews = [NSString stringWithFormat:@"%d", maxNews]; | |
NSLog([NSString stringWithFormat:@"max news timestamp %@", self.lastNews]); | |
NSLog([NSString stringWithFormat:@"max event timestamp %d", maxOccasion]); | |
self.lastOccasion = [NSString stringWithFormat:@"%d", maxOccasion]; | |
[NSThread detachNewThreadSelector: @selector(syncNewsFeed:) | |
toTarget: self withObject: self]; | |
[NSThread detachNewThreadSelector: @selector(syncOccasionFeed:) | |
toTarget: self withObject: self]; | |
//[self syncOccasionFeed]; | |
} | |
/** | |
syncNewsFeed: check for updates to the news feed | |
*/ | |
- (void)syncNewsFeed:(id)sender { | |
NSAutoreleasePool *newsPool = [[NSAutoreleasePool alloc] init]; | |
NSLog(@"fetching news"); | |
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@/stories.plist?last=%@", SERVER, self.lastNews]]]; | |
[self performSelectorOnMainThread:@selector(updateNewsData:) withObject:dict waitUntilDone:YES]; | |
[newsPool release]; | |
[NSThread exit]; | |
} | |
- (void)updateNewsData:(id)dictionary { | |
if (dictionary == nil) { | |
return; | |
} | |
NSDictionary *dict = dictionary; | |
NSLog(@"count: %@", [NSString stringWithFormat:@"%d", [dict count]]); | |
/*for (id key in dict) { | |
NSLog(@"key: %@, value: %@", key, [dict objectForKey:key]); | |
}*/ | |
NSArray *storyIDs = [[dict allKeys] | |
sortedArrayUsingFunction:intSort context:NULL]; | |
// create the fetch request to get all Stories matching the IDs | |
[self managedObjectContext]; | |
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease]; | |
NSEntityDescription *entity = [NSEntityDescription entityForName:@"News" inManagedObjectContext:managedObjectContext]; | |
[fetchRequest setEntity: entity]; | |
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(storyId IN %@)", storyIDs]]; | |
// make sure the results are sorted as well | |
[fetchRequest setSortDescriptors: [NSArray arrayWithObject: | |
[[[NSSortDescriptor alloc] initWithKey: @"storyId" | |
ascending:YES] autorelease]]]; | |
NSError *error; | |
NSArray *storiessMatchingNames = [managedObjectContext | |
executeFetchRequest:fetchRequest error:&error]; | |
NSEnumerator *newStoryIterator = [storyIDs objectEnumerator]; | |
NSEnumerator *existingStoryIterator = [storiessMatchingNames objectEnumerator]; | |
// iterate though the sorted arrays updating existing records or adding new ones | |
News *existingStory; | |
existingStory = [existingStoryIterator nextObject]; | |
id newStory; | |
NSManagedObject *newMO; | |
NSLog(@"existing story count: %@", [NSString stringWithFormat:@"%d", [storyIDs count]]); | |
while (newStory = [newStoryIterator nextObject]) { | |
if ((existingStory != nil) & ([newStory intValue] == [existingStory.storyId intValue])) { | |
NSLog(@"newStory %@ existingStory %@", newStory, [existingStory storyId]); | |
// update the story with the new version | |
[existingStory setValuesForKeysWithDictionary:[dict objectForKey:newStory]]; | |
existingStory = [existingStoryIterator nextObject]; | |
} else { | |
NSLog(@"newStory %@", newStory); | |
newMO = [[NSManagedObject alloc] initWithEntity:entity | |
insertIntoManagedObjectContext:managedObjectContext]; | |
[newMO setValuesForKeysWithDictionary:[dict objectForKey:newStory]]; | |
[newMO release]; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void) createEditableCopyOfDatabaseIfNeeded { | |
// first, test for existence - we don't want to wipe out a user's DB | |
NSFileManager *fileManager = [NSFileManager defaultManager]; | |
NSString *documentsDirectory = [self applicationDocumentsDirectory]; | |
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"USITT_2010.sqlite"]; | |
BOOL dbexists = [fileManager fileExistsAtPath:writableDBPath]; | |
if (!dbexists) { | |
// The writable database does not exist, so copy the default to the appropriate location | |
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"USITT_2010.sqlite"]; | |
NSError *error; | |
BOOL success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error]; | |
if (!success) { | |
NSAssert1(0 , @"Failed to create writable database with message '%@'.", [error localizedDescription]); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void)viewWillAppear:(BOOL)animated { | |
[super viewWillAppear:animated]; | |
if (self.resultsController != nil) { | |
return; | |
} | |
MyAppDelegate *appDelegate = (MyAppDelegate*)[[UIApplication sharedApplication] delegate]; | |
NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext; | |
NSFetchRequest *request = [[NSFetchRequest alloc] init]; | |
NSEntityDescription *entity = [NSEntityDescription entityForName:@"News" inManagedObjectContext:managedObjectContext]; | |
[request setEntity:entity]; | |
//NSPredicate *predicate = [NSPredicate predicateWithFormat:@"captured == YES"]; | |
//[request setPredicate:predicate]; | |
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO]; | |
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; | |
[request setSortDescriptors:sortDescriptors]; | |
[sortDescriptors release]; | |
[sortDescriptor release]; | |
NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"captured_list.cache"]; | |
fetchedResultsController.delegate = self; | |
NSError *error; | |
BOOL success = [fetchedResultsController performFetch:&error]; | |
if (!success) { | |
// Handle the error. | |
} | |
self.resultsController = fetchedResultsController; | |
[request release]; | |
[self.tableView reloadData]; | |
} | |
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { | |
return [[self.resultsController sections] count]; | |
} | |
// Customize the number of rows in the table view. | |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { | |
return [[[self.resultsController sections] objectAtIndex:section] numberOfObjects]; | |
} | |
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { | |
if (indexPath.row == 0 || indexPath.row%2 == 0) { | |
UIColor *altCellColor = [UIColor colorWithWhite:1 alpha:0.1]; | |
cell.backgroundColor = altCellColor; | |
} | |
} | |
// Customize the appearance of table view cells. | |
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { | |
static NSString *CellIdentifier = @"NewsCell"; | |
UILabel *mainLabel, *secondLabel; | |
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; | |
if (cell == nil) { | |
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; | |
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; | |
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(40.0, 0.0, 280.0, 21.0)] autorelease]; | |
mainLabel.tag = 1; | |
mainLabel.font = [UIFont systemFontOfSize:16.0]; | |
mainLabel.textAlignment = UITextAlignmentLeft; | |
mainLabel.textColor = [UIColor blackColor]; | |
mainLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight; | |
[cell.contentView addSubview:mainLabel]; | |
mainLabel.backgroundColor = [UIColor clearColor]; | |
secondLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0.0, 20.0, 280.0, 25.0)] autorelease]; | |
secondLabel.tag = 2; | |
secondLabel.font = [UIFont systemFontOfSize:12.0]; | |
secondLabel.textAlignment = UITextAlignmentRight; | |
secondLabel.textColor = [UIColor darkGrayColor]; | |
secondLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight; | |
[cell.contentView addSubview:secondLabel]; | |
secondLabel.backgroundColor = [UIColor clearColor]; | |
} else { | |
mainLabel = (UILabel *)[cell.contentView viewWithTag:1]; | |
secondLabel = (UILabel *)[cell.contentView viewWithTag:2]; | |
} | |
News *news = [self.resultsController objectAtIndexPath:indexPath]; | |
mainLabel.text = news.title; | |
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease]; | |
[formatter setDateStyle:NSDateFormatterShortStyle]; | |
[formatter setTimeStyle:NSDateFormatterShortStyle]; | |
[formatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]]; | |
secondLabel.text = [formatter stringFromDate:news.date]; | |
return cell; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment