mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-02 17:57:22 +08:00
261 lines
7.0 KiB
Objective-C
261 lines
7.0 KiB
Objective-C
//
|
|
// RKRequestModel.m
|
|
// RestKit
|
|
//
|
|
// Created by Jeff Arena on 4/26/10.
|
|
// Copyright 2010 RestKit. All rights reserved.
|
|
//
|
|
|
|
#import "RKRequestModel.h"
|
|
#import "RKManagedObjectStore.h"
|
|
#import <Three20/Three20.h>
|
|
|
|
@implementation RKRequestModel
|
|
@synthesize objects = _objects;
|
|
@synthesize loaded = _loaded;
|
|
@synthesize resourcePath = _resourcePath;
|
|
@synthesize params = _params;
|
|
@synthesize objectLoader = _objectLoader;
|
|
@synthesize method = _method;
|
|
@synthesize refreshRate = _refreshRate;
|
|
|
|
- (id)initWithResourcePath:(NSString*)resourcePath delegate:(id)delegate {
|
|
if (self = [self init]) {
|
|
_resourcePath = [resourcePath retain];
|
|
_delegate = [delegate retain];
|
|
}
|
|
|
|
[self loadFromObjectCache];
|
|
|
|
return self;
|
|
}
|
|
|
|
/**
|
|
* TODO: These initializers have to set the ivars so the state is configured before loadFromObjectCache is triggered.
|
|
* Do NOT DRY these up by adding dependencies or loadFromObjectCache will fire too early.
|
|
*
|
|
* WARNING
|
|
*/
|
|
|
|
- (id)initWithResourcePath:(NSString*)resourcePath params:(NSDictionary*)params delegate:(id)delegate {
|
|
if (self = [self init]) {
|
|
_resourcePath = [resourcePath retain];
|
|
_delegate = [delegate retain];
|
|
_params = [params retain];
|
|
}
|
|
|
|
[self loadFromObjectCache];
|
|
|
|
return self;
|
|
}
|
|
|
|
- (id)initWithResourcePath:(NSString*)resourcePath params:(NSDictionary*)params objectClass:(Class)klass delegate:(id)delegate {
|
|
if (self = [self init]) {
|
|
_resourcePath = [resourcePath retain];
|
|
_delegate = [delegate retain];
|
|
_params = [params retain];
|
|
_objectClass = [klass retain];
|
|
}
|
|
|
|
[self loadFromObjectCache];
|
|
|
|
return self;
|
|
}
|
|
|
|
- (id)initWithResourcePath:(NSString*)resourcePath params:(NSDictionary*)params objectClass:(Class)klass keyPath:(NSString*)keyPath delegate:(id)delegate {
|
|
if (self = [self init]) {
|
|
_resourcePath = [resourcePath retain];
|
|
_delegate = [delegate retain];
|
|
_params = [params retain];
|
|
_objectClass = [klass retain];
|
|
_keyPath = [keyPath retain];
|
|
}
|
|
|
|
[self loadFromObjectCache];
|
|
|
|
return self;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// NSObject
|
|
|
|
- (id)init {
|
|
if (self = [super init]) {
|
|
_method = RKRequestMethodGET;
|
|
_refreshRate = NSTimeIntervalSince1970; // Essentially, default to never
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[_delegate release];
|
|
[_objectLoader.request cancel];
|
|
[_objectLoader release];
|
|
[_params release];
|
|
[_objects release];
|
|
[_objectClass release];
|
|
[_keyPath release];
|
|
[super dealloc];
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// RKRequestDelegate
|
|
|
|
- (void)requestDidFinishLoad:(RKRequest*)request {
|
|
[self saveLoadedTime];
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidFinishLoad)]) {
|
|
[_delegate rkModelDidFinishLoad];
|
|
}
|
|
}
|
|
|
|
//// TODO: I get replaced...
|
|
- (void)request:(RKRequest*)request didFailLoadWithError:(NSError*)error {
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidFailLoadWithError:)]) {
|
|
[_delegate rkModelDidFailLoadWithError:error];
|
|
}
|
|
}
|
|
|
|
- (void)requestDidCancelLoad:(RKRequest*)request {
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidCancelLoad)]) {
|
|
[_delegate rkModelDidCancelLoad];
|
|
}
|
|
}
|
|
|
|
- (BOOL)needsRefresh {
|
|
NSDate* loadedTime = self.loadedTime;
|
|
BOOL outdated = NO;
|
|
if (loadedTime) {
|
|
outdated = -[loadedTime timeIntervalSinceNow] > _refreshRate;
|
|
} else {
|
|
[self saveLoadedTime];
|
|
}
|
|
return outdated;
|
|
}
|
|
|
|
- (void)clearLoadedTime {
|
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:_resourcePath];
|
|
}
|
|
|
|
- (void)saveLoadedTime {
|
|
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:_resourcePath];
|
|
}
|
|
|
|
- (NSDate*)loadedTime {
|
|
return [[NSUserDefaults standardUserDefaults] objectForKey:_resourcePath];
|
|
}
|
|
|
|
- (void)loadFromObjectCache {
|
|
RKManagedObjectStore* store = [RKObjectManager globalManager].objectStore;
|
|
NSArray* cachedObjects = nil;
|
|
|
|
if (store.managedObjectCache) {
|
|
cachedObjects = [RKManagedObject objectsWithFetchRequests:[store.managedObjectCache fetchRequestsForResourcePath:self.resourcePath]];
|
|
|
|
if (cachedObjects && [cachedObjects count] > 0) {
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidStartLoad)]) {
|
|
[_delegate rkModelDidStartLoad];
|
|
}
|
|
|
|
_objects = [cachedObjects retain];
|
|
_loaded = YES;
|
|
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidLoad)]) {
|
|
[_delegate rkModelDidLoad];
|
|
}
|
|
} else {
|
|
[self load];
|
|
}
|
|
}
|
|
|
|
if ([self needsRefresh]) {
|
|
[self load];
|
|
}
|
|
}
|
|
|
|
- (BOOL)errorWarrantsOptionToGoOffline:(NSError*)error {
|
|
switch ([error code]) {
|
|
case NSURLErrorTimedOut:
|
|
case NSURLErrorCannotFindHost:
|
|
case NSURLErrorCannotConnectToHost:
|
|
case NSURLErrorNetworkConnectionLost:
|
|
case NSURLErrorDNSLookupFailed:
|
|
case NSURLErrorNotConnectedToInternet:
|
|
case NSURLErrorInternationalRoamingOff:
|
|
return YES;
|
|
break;
|
|
default:
|
|
return NO;
|
|
break;
|
|
}
|
|
}
|
|
|
|
- (void)showAlertWithOptionToGoOfflineForError:(NSError*)error {
|
|
UIAlertView* alert = [[[UIAlertView alloc] initWithTitle:TTLocalizedString(@"Network Error", @"")
|
|
message:[error localizedDescription]
|
|
delegate:self
|
|
cancelButtonTitle:TTLocalizedString(@"OK", @"")
|
|
otherButtonTitles:TTLocalizedString(@"Go Offline", @""), nil] autorelease];
|
|
[alert show];
|
|
}
|
|
|
|
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
|
|
// Go Offline button
|
|
if (1 == buttonIndex) {
|
|
[[RKObjectManager globalManager] goOffline];
|
|
}
|
|
}
|
|
|
|
- (void)modelsDidLoad:(NSArray*)models {
|
|
[models retain];
|
|
[_objects release];
|
|
_objects = models;
|
|
_loaded = YES;
|
|
|
|
// NOTE: You must finish load after clearing the loadingRequest and setting the loaded flag
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidLoad)]) {
|
|
[_delegate rkModelDidLoad];
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// RKModelLoaderDelegate
|
|
|
|
// This callback is invoked after the request has been fully serviced. Finish the load here.
|
|
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
|
|
[objectLoader release];
|
|
_objectLoader = nil;
|
|
[self modelsDidLoad:objects];
|
|
}
|
|
|
|
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
|
|
[objectLoader release];
|
|
_objectLoader = nil;
|
|
if ([self errorWarrantsOptionToGoOffline:error]) {
|
|
[self showAlertWithOptionToGoOfflineForError:error];
|
|
} else {
|
|
[_delegate didFailLoadWithError:error];
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// public
|
|
|
|
- (void)reset {
|
|
[self clearLoadedTime];
|
|
}
|
|
|
|
- (void)load {
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidStartLoad)]) {
|
|
[_delegate rkModelDidStartLoad];
|
|
}
|
|
|
|
_objectLoader = [[[RKObjectManager globalManager] objectLoaderWithResourcePath:_resourcePath delegate:self] retain];
|
|
_objectLoader.method = _method;
|
|
_objectLoader.objectClass = _objectClass;
|
|
_objectLoader.keyPath = _keyPath;
|
|
_objectLoader.params = _params;
|
|
[_objectLoader send];
|
|
}
|
|
|
|
@end
|