mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-04 22:58:14 +08:00
274 lines
7.1 KiB
Objective-C
274 lines
7.1 KiB
Objective-C
//
|
|
// RKRequestTTModel.m
|
|
// RestKit
|
|
//
|
|
// Created by Blake Watters on 2/9/10.
|
|
// Copyright 2010 Two Toasters. All rights reserved.
|
|
//
|
|
|
|
#import "RKRequestTTModel.h"
|
|
#import "RKManagedObjectStore.h"
|
|
#import "../Network/Network.h"
|
|
|
|
|
|
static NSTimeInterval defaultRefreshRate = NSTimeIntervalSince1970;
|
|
static NSString* const kDefaultLoadedTimeKey = @"RKRequestTTModelDefaultLoadedTimeKey";
|
|
|
|
@interface RKRequestTTModel (Private)
|
|
|
|
- (void)clearLoadedTime;
|
|
- (void)saveLoadedTime;
|
|
- (BOOL)errorWarrantsOptionToGoOffline:(NSError*)error;
|
|
- (void)showAlertWithOptionToGoOfflineForError:(NSError*)error;
|
|
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
|
|
- (void)modelsDidLoad:(NSArray*)models;
|
|
- (void)load;
|
|
|
|
@end
|
|
|
|
|
|
@implementation RKRequestTTModel
|
|
|
|
@synthesize objects = _objects;
|
|
@synthesize resourcePath = _resourcePath;
|
|
@synthesize params = _params;
|
|
@synthesize method = _method;
|
|
@synthesize refreshRate = _refreshRate;
|
|
|
|
+ (NSDate*)defaultLoadedTime {
|
|
NSDate* defaultLoadedTime = [[NSUserDefaults standardUserDefaults] objectForKey:kDefaultLoadedTimeKey];
|
|
if (defaultLoadedTime == nil) {
|
|
defaultLoadedTime = [NSDate date];
|
|
[[NSUserDefaults standardUserDefaults] setObject:defaultLoadedTime forKey:kDefaultLoadedTimeKey];
|
|
}
|
|
|
|
return defaultLoadedTime;
|
|
}
|
|
|
|
+ (NSTimeInterval)defaultRefreshRate {
|
|
return defaultRefreshRate;
|
|
}
|
|
|
|
+ (void)setDefaultRefreshRate:(NSTimeInterval)newDefaultRefreshRate {
|
|
defaultRefreshRate = newDefaultRefreshRate;
|
|
}
|
|
|
|
- (id)initWithResourcePath:(NSString*)resourcePath {
|
|
self = [self init];
|
|
if (self) {
|
|
_resourcePath = [resourcePath retain];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (id)initWithResourcePath:(NSString*)resourcePath params:(NSDictionary*)params {
|
|
self = [self initWithResourcePath:resourcePath];
|
|
if (self) {
|
|
self.params = [params retain];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (id)initWithResourcePath:(NSString*)resourcePath params:(NSDictionary*)params objectClass:(Class)klass {
|
|
self = [self initWithResourcePath:resourcePath params:params];
|
|
if (self) {
|
|
_objectClass = [klass retain];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (id)initWithResourcePath:(NSString*)resourcePath params:(NSDictionary*)params objectClass:(Class)klass keyPath:(NSString*)keyPath {
|
|
self = [self initWithResourcePath:resourcePath params:params objectClass:klass];
|
|
if (self) {
|
|
_keyPath = [keyPath retain];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (id)initWithResourcePath:(NSString*)resourcePath params:(NSDictionary*)params method:(RKRequestMethod)method {
|
|
self = [self initWithResourcePath:resourcePath params:params];
|
|
if (self) {
|
|
_method = method;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// NSObject
|
|
|
|
- (id)init {
|
|
self = [super init];
|
|
if (self) {
|
|
self.method = RKRequestMethodGET;
|
|
self.refreshRate = [RKRequestTTModel defaultRefreshRate];
|
|
self.params = nil;
|
|
_cacheLoaded = NO;
|
|
_objects = nil;
|
|
_isLoaded = NO;
|
|
_isLoading = NO;
|
|
_resourcePath = nil;
|
|
_emptyReloadAttempted = NO;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[[RKRequestQueue sharedQueue] cancelRequestsWithDelegate:self];
|
|
[_objects release];
|
|
_objects = nil;
|
|
[_resourcePath release];
|
|
_resourcePath = nil;
|
|
[_objectClass release];
|
|
_objectClass = nil;
|
|
[_keyPath release];
|
|
_keyPath = nil;
|
|
self.params = nil;
|
|
[super dealloc];
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// TTModel
|
|
|
|
- (BOOL)isLoaded {
|
|
return _isLoaded;
|
|
}
|
|
|
|
- (BOOL)isLoading {
|
|
return _isLoading;
|
|
}
|
|
|
|
- (BOOL)isLoadingMore {
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)isOutdated {
|
|
NSTimeInterval sinceNow = [self.loadedTime timeIntervalSinceNow];
|
|
if (![self isLoading] && !_emptyReloadAttempted && _objects && [_objects count] == 0) {
|
|
_emptyReloadAttempted = YES;
|
|
return YES;
|
|
}
|
|
return (![self isLoading] && (-sinceNow > _refreshRate));
|
|
}
|
|
|
|
- (void)cancel {
|
|
[[RKRequestQueue sharedQueue] cancelRequestsWithDelegate:self];
|
|
[self didCancelLoad];
|
|
}
|
|
|
|
- (void)invalidate:(BOOL)erase {
|
|
// TODO: Note sure how to handle erase...
|
|
[self clearLoadedTime];
|
|
}
|
|
|
|
- (void)load:(TTURLRequestCachePolicy)cachePolicy more:(BOOL)more {
|
|
[self load];
|
|
}
|
|
|
|
- (NSDate*)loadedTime {
|
|
NSDate* loadedTime = [[NSUserDefaults standardUserDefaults] objectForKey:_resourcePath];
|
|
if (loadedTime == nil) {
|
|
return [RKRequestTTModel defaultLoadedTime];
|
|
}
|
|
return loadedTime;
|
|
}
|
|
|
|
#pragma mark RKModelLoaderDelegate
|
|
|
|
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
|
|
_isLoading = NO;
|
|
[self saveLoadedTime];
|
|
[self modelsDidLoad:objects];
|
|
}
|
|
|
|
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
|
|
_isLoading = NO;
|
|
[self didFailLoadWithError:error];
|
|
// if ([self errorWarrantsOptionToGoOffline:error]) {
|
|
// [self showAlertWithOptionToGoOfflineForError:error];
|
|
// }
|
|
}
|
|
|
|
- (void)objectLoaderDidLoadUnexpectedResponse:(RKObjectLoader*)objectLoader {
|
|
_isLoading = NO;
|
|
|
|
// TODO: Passing a nil error here does nothing for Three20. Need to construct our
|
|
// own error here to make Three20 happy??
|
|
[self didFailLoadWithError:nil];
|
|
}
|
|
|
|
|
|
#pragma mark RKRequestTTModel (Private)
|
|
|
|
- (void)clearLoadedTime {
|
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:_resourcePath];
|
|
}
|
|
|
|
- (void)saveLoadedTime {
|
|
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:_resourcePath];
|
|
}
|
|
|
|
- (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:nil
|
|
cancelButtonTitle:TTLocalizedString(@"OK", @"")
|
|
otherButtonTitles:nil] autorelease];
|
|
[alert show];
|
|
}
|
|
|
|
- (void)modelsDidLoad:(NSArray*)models {
|
|
[models retain];
|
|
[_objects release];
|
|
_objects = nil;
|
|
|
|
_objects = models;
|
|
_isLoaded = YES;
|
|
|
|
[self didFinishLoad];
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// public
|
|
|
|
- (void)load {
|
|
RKManagedObjectStore* store = [RKObjectManager sharedManager].objectStore;
|
|
NSArray* cacheFetchRequests = nil;
|
|
if (store.managedObjectCache) {
|
|
cacheFetchRequests = [store.managedObjectCache fetchRequestsForResourcePath:self.resourcePath];
|
|
}
|
|
|
|
if (!store.managedObjectCache || !cacheFetchRequests || _cacheLoaded) {
|
|
RKObjectLoader* objectLoader = [[RKObjectManager sharedManager] objectLoaderWithResourcePath:_resourcePath delegate:self];
|
|
objectLoader.method = self.method;
|
|
objectLoader.objectClass = _objectClass;
|
|
objectLoader.keyPath = _keyPath;
|
|
objectLoader.params = self.params;
|
|
|
|
_isLoading = YES;
|
|
[self didStartLoad];
|
|
[objectLoader send];
|
|
} else if (cacheFetchRequests && !_cacheLoaded) {
|
|
_cacheLoaded = YES;
|
|
[self modelsDidLoad:[RKManagedObject objectsWithFetchRequests:cacheFetchRequests]];
|
|
}
|
|
}
|
|
|
|
@end
|