mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-04 22:58:14 +08:00
235 lines
6.5 KiB
Objective-C
235 lines
6.5 KiB
Objective-C
//
|
|
// RKRequestModel.m
|
|
// RestKit
|
|
//
|
|
// Created by Jeff Arena on 4/26/10.
|
|
// Copyright 2010 RestKit. All rights reserved.
|
|
//
|
|
|
|
#import "RKRequestModel.h"
|
|
#import <Three20/Three20.h>
|
|
|
|
@implementation RKRequestModel
|
|
@synthesize objects = _objects;
|
|
@synthesize loaded = _loaded;
|
|
@synthesize resourcePath = _resourcePath;
|
|
@synthesize params = _params;
|
|
@synthesize loadingRequest = _loadingRequest;
|
|
@synthesize method = _method;
|
|
@synthesize fetchRequest = _fetchRequest;
|
|
@synthesize refreshRate = _refreshRate;
|
|
|
|
+ (id)modelWithResourcePath:(NSString*)resourcePath delegate:(id)delegate {
|
|
return [[[self alloc] initWithResourcePath:resourcePath delegate:delegate] autorelease];
|
|
}
|
|
|
|
+ (id)modelWithResourcePath:(NSString*)resourcePath params:(NSDictionary*)params delegate:(id)delegate {
|
|
return [[[self alloc] initWithResourcePath:resourcePath params:params delegate:delegate] autorelease];
|
|
}
|
|
|
|
- (id)initWithResourcePath:(NSString*)resourcePath delegate:(id)delegate {
|
|
if (self = [self init]) {
|
|
_resourcePath = [resourcePath retain];
|
|
_delegate = [delegate retain];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (id)initWithResourcePath:(NSString*)resourcePath params:(NSDictionary*)params delegate:(id)delegate {
|
|
if (self = [self init]) {
|
|
_resourcePath = [resourcePath retain];
|
|
_params = [params retain];
|
|
_delegate = [delegate retain];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// NSObject
|
|
|
|
- (id)init {
|
|
if (self = [super init]) {
|
|
_loadingRequest = nil;
|
|
_objects = nil;
|
|
_delegate = nil;
|
|
_params = nil;
|
|
_loaded = NO;
|
|
_method = RKRequestMethodGET;
|
|
_fetchRequest = nil;
|
|
_refreshRate = (60*60); // 1 hour default
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[_delegate release];
|
|
[_loadingRequest cancel];
|
|
[_loadingRequest release];
|
|
_loadingRequest = nil;
|
|
[_params release];
|
|
_params = nil;
|
|
[_objects release];
|
|
_objects = nil;
|
|
[_fetchRequest release];
|
|
[super dealloc];
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// RKRequestDelegate
|
|
|
|
- (void)requestDidStartLoad:(RKRequest*)request {
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidStartLoad)]) {
|
|
[_delegate rkModelDidStartLoad];
|
|
}
|
|
}
|
|
|
|
- (void)requestDidFinishLoad:(RKRequest*)request {
|
|
[self saveLoadedTime];
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidFinishLoad)]) {
|
|
[_delegate rkModelDidFinishLoad];
|
|
}
|
|
[_loadingRequest release];_loadingRequest=nil;
|
|
}
|
|
|
|
// TODO: I get replaced...
|
|
- (void)request:(RKRequest*)request didFailLoadWithError:(NSError*)error {
|
|
[_loadingRequest release];_loadingRequest=nil;
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidFailLoadWithError:)]) {
|
|
[_delegate rkModelDidFailLoadWithError:error];
|
|
}
|
|
}
|
|
|
|
- (void)requestDidCancelLoad:(RKRequest*)request {
|
|
[_loadingRequest release];_loadingRequest=nil;
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidCancelLoad)]) {
|
|
[_delegate rkModelDidCancelLoad];
|
|
}
|
|
}
|
|
|
|
- (BOOL)needsRefresh {
|
|
NSDate* loadedTime = self.loadedTime;
|
|
if (loadedTime) {
|
|
BOOL outdated = -[loadedTime timeIntervalSinceNow] > _refreshRate;
|
|
return outdated;
|
|
}
|
|
return YES;
|
|
}
|
|
|
|
- (void)clearLoadedTime {
|
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:_resourcePath];
|
|
}
|
|
|
|
- (void)saveLoadedTime {
|
|
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:_resourcePath];
|
|
}
|
|
|
|
- (NSDate*)loadedTime {
|
|
return [[NSUserDefaults standardUserDefaults] objectForKey:_resourcePath];
|
|
}
|
|
|
|
- (void)loadFromObjectCache {
|
|
if (_fetchRequest != nil) {
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidStartLoad)]) {
|
|
[_delegate rkModelDidStartLoad];
|
|
}
|
|
|
|
_objects = [[RKManagedObject objectsWithRequest:_fetchRequest] retain];
|
|
_loaded = YES;
|
|
|
|
if ([_delegate respondsToSelector:@selector(rkModelDidFinishLoad)]) {
|
|
[_delegate rkModelDidFinishLoad];
|
|
}
|
|
|
|
// TODO: What if self.needsRefresh does the update 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)resourceLoadRequest:(RKRequest *)request didLoadObjects:(NSArray *)objects response:(RKResponse *)response object:(id<RKObjectMappable>)object {
|
|
[self modelsDidLoad:objects];
|
|
}
|
|
|
|
- (void)resourceLoadRequest:(RKRequest*)request didFailWithError:(NSError*)error response:(RKResponse*)response object:(id<RKObjectMappable>)object {
|
|
if ([self errorWarrantsOptionToGoOffline:error]) {
|
|
[self showAlertWithOptionToGoOfflineForError:error];
|
|
} else {
|
|
[_delegate didFailLoadWithError:error];
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// public
|
|
|
|
- (void)setFetchRequest:(NSFetchRequest*)fetchRequest {
|
|
[_fetchRequest release];
|
|
_fetchRequest = [fetchRequest retain];
|
|
[self loadFromObjectCache];
|
|
}
|
|
|
|
- (void)reset {
|
|
[self clearLoadedTime];
|
|
}
|
|
|
|
- (void)load {
|
|
if (_params) {
|
|
_loadingRequest = [[RKObjectManager globalManager] loadResource:_resourcePath fetchRequest:_fetchRequest method:_method params:_params delegate:self];
|
|
} else {
|
|
_loadingRequest = [[RKObjectManager globalManager] loadResource:_resourcePath fetchRequest:_fetchRequest method:_method delegate:self];
|
|
}
|
|
}
|
|
|
|
@end
|