mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-24 04:46:01 +08:00
Modernize and restore all example projects. closes #1007
This commit is contained in:
@@ -9,42 +9,41 @@
|
||||
#import <RestKit/RestKit.h>
|
||||
#import <RestKit/CoreData.h>
|
||||
|
||||
@interface RKTStatus : NSManagedObject {
|
||||
}
|
||||
@interface RKTStatus : NSManagedObject
|
||||
|
||||
/**
|
||||
* The unique ID of this Status
|
||||
The unique ID of this Status
|
||||
*/
|
||||
@property (nonatomic, retain) NSNumber *statusID;
|
||||
@property (nonatomic, copy) NSNumber *statusID;
|
||||
|
||||
/**
|
||||
* Timestamp the Status was sent
|
||||
Timestamp the Status was sent
|
||||
*/
|
||||
@property (nonatomic, retain) NSDate *createdAt;
|
||||
@property (nonatomic, copy) NSDate *createdAt;
|
||||
|
||||
/**
|
||||
* Text of the Status
|
||||
Text of the Status
|
||||
*/
|
||||
@property (nonatomic, retain) NSString *text;
|
||||
@property (nonatomic, copy) NSString *text;
|
||||
|
||||
/**
|
||||
* String version of the URL associated with the Status
|
||||
String version of the URL associated with the Status
|
||||
*/
|
||||
@property (nonatomic, retain) NSString *urlString;
|
||||
@property (nonatomic, copy) NSString *urlString;
|
||||
|
||||
/**
|
||||
* The screen name of the User this Status was in response to
|
||||
The screen name of the User this Status was in response to
|
||||
*/
|
||||
@property (nonatomic, retain) NSString *inReplyToScreenName;
|
||||
@property (nonatomic, copy) NSString *inReplyToScreenName;
|
||||
|
||||
/**
|
||||
* Is this status a favorite?
|
||||
Is this status a favorite?
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL isFavorited;
|
||||
|
||||
/**
|
||||
* The User who posted this status
|
||||
The User who posted this status
|
||||
*/
|
||||
@property (nonatomic, retain) NSManagedObject *user;
|
||||
@property (nonatomic, strong) NSManagedObject *user;
|
||||
|
||||
@end
|
||||
|
||||
@@ -8,9 +8,5 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
@interface RKTwitterAppDelegate : NSObject <UIApplicationDelegate> {
|
||||
}
|
||||
|
||||
@interface RKTwitterAppDelegate : UIResponder <UIApplicationDelegate>
|
||||
@end
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
@implementation RKTwitterAppDelegate
|
||||
|
||||
@synthesize window;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Application lifecycle
|
||||
|
||||
@@ -23,44 +25,51 @@
|
||||
NSURL *baseURL = [NSURL URLWithString:@"http://twitter.com"];
|
||||
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL];
|
||||
|
||||
// Enable automatic network activity indicator management
|
||||
objectManager.client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
|
||||
// Enable Activity Indicator Spinner
|
||||
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
|
||||
|
||||
// Initialize managed object store
|
||||
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
|
||||
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
|
||||
objectManager.managedObjectStore = managedObjectStore;
|
||||
[managedObjectStore release];
|
||||
|
||||
// Setup our object mappings
|
||||
/*!
|
||||
/**
|
||||
Mapping by entity. Here we are configuring a mapping by targetting a Core Data entity with a specific
|
||||
name. This allows us to map back Twitter user objects directly onto NSManagedObject instances --
|
||||
there is no backing model class!
|
||||
*/
|
||||
RKEntityMapping *userMapping = [RKEntityMapping mappingForEntityForName:@"RKTUser" inManagedObjectStore:managedObjectStore];
|
||||
userMapping.primaryKeyAttribute = @"userID";
|
||||
[userMapping mapKeyPath:@"id" toAttribute:@"userID"];
|
||||
[userMapping mapKeyPath:@"screen_name" toAttribute:@"screenName"];
|
||||
[userMapping mapAttributes:@"name", nil];
|
||||
[userMapping addAttributeMappingsFromDictionary:@{
|
||||
@"id": @"userID",
|
||||
@"screen_name": @"screenName",
|
||||
}];
|
||||
// If source and destination key path are the same, we can simply add a string to the array
|
||||
[userMapping addAttributeMappingsFromArray:@[ @"name" ]];
|
||||
|
||||
RKEntityMapping *statusMapping = [RKEntityMapping mappingForEntityForName:@"RKTStatus" inManagedObjectStore:managedObjectStore];
|
||||
statusMapping.primaryKeyAttribute = @"statusID";
|
||||
[statusMapping mapKeyPathsToAttributes:@"id", @"statusID",
|
||||
@"created_at", @"createdAt",
|
||||
@"text", @"text",
|
||||
@"url", @"urlString",
|
||||
@"in_reply_to_screen_name", @"inReplyToScreenName",
|
||||
@"favorited", @"isFavorited",
|
||||
nil];
|
||||
[statusMapping mapRelationship:@"user" withMapping:userMapping];
|
||||
[statusMapping addAttributeMappingsFromDictionary:@{
|
||||
@"id": @"statusID",
|
||||
@"created_at": @"createdAt",
|
||||
@"text": @"text",
|
||||
@"url": @"urlString",
|
||||
@"in_reply_to_screen_name": @"inReplyToScreenName",
|
||||
@"favorited": @"isFavorited",
|
||||
}];
|
||||
[statusMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"user" toKeyPath:@"user" withMapping:userMapping]];
|
||||
|
||||
// Update date format so that we can parse Twitter dates properly
|
||||
// Wed Sep 29 15:31:08 +0000 2010
|
||||
[RKObjectMapping addDefaultDateFormatterForString:@"E MMM d HH:mm:ss Z y" inTimeZone:nil];
|
||||
|
||||
// Register our mappings with the provider
|
||||
[objectManager.mappingProvider setObjectMapping:statusMapping forResourcePathPattern:@"/status/user_timeline/:username"];
|
||||
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:statusMapping
|
||||
pathPattern:@"/status/user_timeline/:username"
|
||||
keyPath:nil
|
||||
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
|
||||
[objectManager addResponseDescriptor:responseDescriptor];
|
||||
|
||||
// Uncomment this to use XML, comment it to use JSON
|
||||
// objectManager.acceptMIMEType = RKMIMETypeXML;
|
||||
@@ -93,6 +102,8 @@
|
||||
} else {
|
||||
RKLogError(@"Failed to finish import and save seed database due to error: %@", error);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
#else
|
||||
/**
|
||||
Complete Core Data stack initialization
|
||||
@@ -108,16 +119,9 @@
|
||||
[managedObjectStore createManagedObjectContexts];
|
||||
|
||||
// Configure a managed object cache to ensure we do not create duplicate objects
|
||||
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.primaryManagedObjectContext];
|
||||
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
|
||||
#endif
|
||||
|
||||
// Create Window and View Controllers
|
||||
RKTwitterViewController *viewController = [[[RKTwitterViewController alloc] initWithNibName:nil bundle:nil] autorelease];
|
||||
UINavigationController *controller = [[UINavigationController alloc] initWithRootViewController:viewController];
|
||||
UIWindow *window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
|
||||
[window addSubview:controller.view];
|
||||
[window makeKeyAndVisible];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,5 +10,4 @@
|
||||
#import <RestKit/RestKit.h>
|
||||
|
||||
@interface RKTwitterViewController : UIViewController
|
||||
- (void)loadObjectsFromDataStore;
|
||||
@end
|
||||
|
||||
@@ -9,97 +9,78 @@
|
||||
#import "RKTwitterViewController.h"
|
||||
#import "RKTStatus.h"
|
||||
|
||||
@interface RKTwitterViewController () <UITableViewDelegate, UITableViewDataSource, RKObjectLoaderDelegate>
|
||||
@property (nonatomic, retain) UITableView *tableView;
|
||||
@property (nonatomic, retain) NSArray *statuses;
|
||||
static void RKTwitterShowAlertWithError(NSError *error)
|
||||
{
|
||||
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
|
||||
message:[error localizedDescription]
|
||||
delegate:nil
|
||||
cancelButtonTitle:@"OK" otherButtonTitles:nil];
|
||||
[alert show];
|
||||
}
|
||||
|
||||
@interface RKTwitterViewController () <UITableViewDelegate, UITableViewDataSource>
|
||||
@property (nonatomic, weak) IBOutlet UITableView *tableView;
|
||||
@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
|
||||
@end
|
||||
|
||||
@implementation RKTwitterViewController
|
||||
|
||||
@synthesize tableView = _tableView;
|
||||
@synthesize statuses = _statuses;
|
||||
|
||||
- (void)loadView
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super loadView];
|
||||
[super viewDidLoad];
|
||||
|
||||
// Set debug logging level. Set to 'RKLogLevelTrace' to see JSON payload
|
||||
RKLogConfigureByName("RestKit/Network", RKLogLevelDebug);
|
||||
|
||||
// Setup View and Table View
|
||||
self.title = @"RestKit Tweets";
|
||||
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;
|
||||
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
|
||||
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(reloadButtonWasPressed:)] autorelease];
|
||||
|
||||
UIImageView *imageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"BG.png"]] autorelease];
|
||||
imageView.frame = CGRectOffset(imageView.frame, 0, -64);
|
||||
|
||||
[self.view insertSubview:imageView atIndex:0];
|
||||
|
||||
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 480-64) style:UITableViewStylePlain];
|
||||
self.tableView.dataSource = self;
|
||||
self.tableView.delegate = self;
|
||||
self.tableView.backgroundColor = [UIColor clearColor];
|
||||
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
[self.view addSubview:self.tableView];
|
||||
|
||||
// Load statuses from core data
|
||||
[self loadObjectsFromDataStore];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_tableView release];
|
||||
[_statuses release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)loadObjectsFromDataStore
|
||||
{
|
||||
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"RKTStatus"];
|
||||
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:NO];
|
||||
fetchRequest.sortDescriptors = @[descriptor];
|
||||
NSError *error;
|
||||
self.statuses = [[RKManagedObjectStore defaultStore].mainQueueManagedObjectContext executeFetchRequest:fetchRequest error:&error];
|
||||
NSError *error = nil;
|
||||
|
||||
// Setup fetched results
|
||||
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
|
||||
managedObjectContext:[RKManagedObjectStore defaultStore].mainQueueManagedObjectContext
|
||||
sectionNameKeyPath:nil
|
||||
cacheName:nil];
|
||||
BOOL fetchSuccessful = [self.fetchedResultsController performFetch:&error];
|
||||
if (! fetchSuccessful) {
|
||||
RKTwitterShowAlertWithError(error);
|
||||
}
|
||||
|
||||
[self loadData];
|
||||
}
|
||||
|
||||
|
||||
- (void)loadData
|
||||
{
|
||||
// Load the object model via RestKit
|
||||
RKObjectManager *objectManager = [RKObjectManager sharedManager];
|
||||
[objectManager loadObjectsAtResourcePath:@"/status/user_timeline/RestKit" delegate:self];
|
||||
[[RKObjectManager sharedManager] getObjectsAtPath:@"/status/user_timeline/RestKit" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
|
||||
RKLogInfo(@"Load complete: Table should refresh...");
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:@"LastUpdatedAt"];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
|
||||
RKLogError(@"Load failed with error: %@", error);
|
||||
|
||||
RKTwitterShowAlertWithError(error);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)reloadButtonWasPressed:(id)sender
|
||||
- (IBAction)refresh:(id)sender
|
||||
{
|
||||
// Load the object model via RestKit
|
||||
[self loadData];
|
||||
}
|
||||
|
||||
#pragma mark RKObjectLoaderDelegate methods
|
||||
|
||||
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:@"LastUpdatedAt"];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
NSLog(@"Loaded statuses: %@", objects);
|
||||
[self loadObjectsFromDataStore];
|
||||
[_tableView reloadData];
|
||||
}
|
||||
|
||||
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error
|
||||
{
|
||||
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Error"
|
||||
message:[error localizedDescription]
|
||||
delegate:nil
|
||||
cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
|
||||
[alert show];
|
||||
NSLog(@"Hit error: %@", error);
|
||||
}
|
||||
|
||||
#pragma mark UITableViewDelegate methods
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
CGSize size = [[[_statuses objectAtIndex:indexPath.row] text] sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(300, 9000)];
|
||||
RKTStatus *status = [self.fetchedResultsController objectAtIndexPath:indexPath];
|
||||
CGSize size = [[status text] sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(300, 9000)];
|
||||
return size.height + 10;
|
||||
}
|
||||
|
||||
@@ -107,7 +88,8 @@
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return [_statuses count];
|
||||
id<NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController.sections objectAtIndex:section];
|
||||
return [sectionInfo numberOfObjects];
|
||||
}
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
|
||||
@@ -125,13 +107,13 @@
|
||||
NSString *reuseIdentifier = @"Tweet Cell";
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
|
||||
if (nil == cell) {
|
||||
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier] autorelease];
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
|
||||
cell.textLabel.font = [UIFont systemFontOfSize:14];
|
||||
cell.textLabel.numberOfLines = 0;
|
||||
cell.textLabel.backgroundColor = [UIColor clearColor];
|
||||
cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"listbg.png"]];
|
||||
}
|
||||
RKTStatus *status = [_statuses objectAtIndex:indexPath.row];
|
||||
RKTStatus *status = [self.fetchedResultsController objectAtIndexPath:indexPath];
|
||||
cell.textLabel.text = status.text;
|
||||
return cell;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user