From cc9ea3ee6cc22a77fd4019f5186cbb6e0b6abe2f Mon Sep 17 00:00:00 2001 From: Jeremy Ellison Date: Tue, 19 Oct 2010 10:12:49 -0400 Subject: [PATCH 1/4] don't crash the sbjson parser --- Code/Support/Parsers/JSON/RKJSONParser+SBJSON.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Support/Parsers/JSON/RKJSONParser+SBJSON.m b/Code/Support/Parsers/JSON/RKJSONParser+SBJSON.m index 956948d1..077fb15c 100644 --- a/Code/Support/Parsers/JSON/RKJSONParser+SBJSON.m +++ b/Code/Support/Parsers/JSON/RKJSONParser+SBJSON.m @@ -14,11 +14,11 @@ - (NSDictionary*)objectFromString:(NSString*)string { SBJsonParser* parser = [[SBJsonParser alloc] init]; id result = [parser objectWithString:string]; - [parser release]; if (nil == result) { // TODO: Need to surface these errors in a better fashion NSLog(@"[RestKit] RKMappingFormatJSONParser: Parser failed with error trace: %@ and string: %@", [parser errorTrace], string); } + [parser release]; return result; } From 89f26fbe7f889e2d5b6b36e454ea1a55c5107c4e Mon Sep 17 00:00:00 2001 From: Jeff Arena Date: Tue, 19 Oct 2010 10:28:34 -0400 Subject: [PATCH 2/4] fix use of released object in debug message by relocating the release call --- Code/Support/Parsers/JSON/RKJSONParser+SBJSON.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Support/Parsers/JSON/RKJSONParser+SBJSON.m b/Code/Support/Parsers/JSON/RKJSONParser+SBJSON.m index 956948d1..077fb15c 100644 --- a/Code/Support/Parsers/JSON/RKJSONParser+SBJSON.m +++ b/Code/Support/Parsers/JSON/RKJSONParser+SBJSON.m @@ -14,11 +14,11 @@ - (NSDictionary*)objectFromString:(NSString*)string { SBJsonParser* parser = [[SBJsonParser alloc] init]; id result = [parser objectWithString:string]; - [parser release]; if (nil == result) { // TODO: Need to surface these errors in a better fashion NSLog(@"[RestKit] RKMappingFormatJSONParser: Parser failed with error trace: %@ and string: %@", [parser errorTrace], string); } + [parser release]; return result; } From 82e2a2792daa0111c63567041bff0da8c8bbd782 Mon Sep 17 00:00:00 2001 From: Jeff Arena Date: Tue, 19 Oct 2010 11:05:03 -0400 Subject: [PATCH 3/4] fix issue with missing loader reference to objectstore; removed use of singleton to access store reference in the loader --- Code/ObjectMapping/RKObjectLoader.m | 8 ++++---- Code/ObjectMapping/RKObjectManager.m | 7 +++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Code/ObjectMapping/RKObjectLoader.m b/Code/ObjectMapping/RKObjectLoader.m index b4b3ee1e..8d4908a3 100644 --- a/Code/ObjectMapping/RKObjectLoader.m +++ b/Code/ObjectMapping/RKObjectLoader.m @@ -145,7 +145,7 @@ - (void)processLoadModelsInBackground:(RKResponse *)response { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - RKManagedObjectStore* objectStore = [[RKObjectManager globalManager] objectStore]; // TODO: Should probably relax singleton... + RKManagedObjectStore* objectStore = self.managedObjectStore; // If the request was sent through a model, we map the results back into that object // TODO: Note that this assumption may not work in all cases, other approaches? @@ -174,10 +174,10 @@ results = [NSArray arrayWithObjects:result, nil]; } - if (self.managedObjectStore && [self.managedObjectStore managedObjectCache]) { + if (objectStore && [objectStore managedObjectCache]) { if ([self.URL isKindOfClass:[RKURL class]]) { RKURL* rkURL = (RKURL*)self.URL; - NSArray* fetchRequests = [[self.managedObjectStore managedObjectCache] fetchRequestsForResourcePath:rkURL.resourcePath]; + NSArray* fetchRequests = [[objectStore managedObjectCache] fetchRequestsForResourcePath:rkURL.resourcePath]; NSArray* cachedObjects = [RKManagedObject objectsWithFetchRequests:fetchRequests]; for (id object in cachedObjects) { if ([object isKindOfClass:[RKManagedObject class]]) { @@ -192,7 +192,7 @@ // Before looking up NSManagedObjectIDs, need to save to ensure we do not have // temporary IDs for new objects prior to handing the objectIDs across threads - NSError* error = [self.managedObjectStore save]; + NSError* error = [objectStore save]; if (nil != error) { NSDictionary* infoDictionary = [[NSDictionary dictionaryWithObjectsAndKeys:response, @"response", error, @"error", nil] retain]; [self performSelectorOnMainThread:@selector(informDelegateOfObjectLoadErrorWithInfoDictionary:) withObject:infoDictionary waitUntilDone:NO]; diff --git a/Code/ObjectMapping/RKObjectManager.m b/Code/ObjectMapping/RKObjectManager.m index 32508524..56f28be2 100644 --- a/Code/ObjectMapping/RKObjectManager.m +++ b/Code/ObjectMapping/RKObjectManager.m @@ -107,8 +107,11 @@ static RKObjectManager* globalManager = nil; } // Grab request through client to get HTTP AUTH & Headers - RKRequest* request = [self.client requestWithResourcePath:resourcePath delegate:nil callback:nil]; - return [RKObjectLoader loaderWithMapper:self.mapper request:request delegate:delegate]; + RKRequest* request = [self.client requestWithResourcePath:resourcePath delegate:nil callback:nil]; + RKObjectLoader* loader = [RKObjectLoader loaderWithMapper:self.mapper request:request delegate:delegate]; + loader.managedObjectStore = self.objectStore; + + return loader; } ///////////////////////////////////////////////////////////// From 92b39313f03dce37f401f50282de314d8d778859 Mon Sep 17 00:00:00 2001 From: Blake Watters Date: Tue, 19 Oct 2010 14:21:39 -0400 Subject: [PATCH 4/4] Fixed bug with load happening too soon --- Code/ObjectMapping/RKObjectLoader.m | 3 +- Code/Three20/RKRequestModel.m | 80 +++++++++++++++++++---------- 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/Code/ObjectMapping/RKObjectLoader.m b/Code/ObjectMapping/RKObjectLoader.m index 8d4908a3..f85dff33 100644 --- a/Code/ObjectMapping/RKObjectLoader.m +++ b/Code/ObjectMapping/RKObjectLoader.m @@ -163,8 +163,7 @@ [_mapper mapObject:mainThreadModel fromString:[response bodyAsString]]; results = [NSArray arrayWithObject:mainThreadModel]; } - } else { - + } else { id result = [_mapper mapFromString:[response bodyAsString] toClass:self.objectClass keyPath:_keyPath]; if ([result isKindOfClass:[NSArray class]]) { results = (NSArray*)result; diff --git a/Code/Three20/RKRequestModel.m b/Code/Three20/RKRequestModel.m index c5c61b5f..8a73d9b8 100644 --- a/Code/Three20/RKRequestModel.m +++ b/Code/Three20/RKRequestModel.m @@ -24,29 +24,55 @@ _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 initWithResourcePath:resourcePath delegate: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 initWithResourcePath:resourcePath params:params delegate: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 initWithResourcePath:resourcePath params:params objectClass:klass delegate:delegate]) { + if (self = [self init]) { + _resourcePath = [resourcePath retain]; + _delegate = [delegate retain]; + _params = [params retain]; + _objectClass = [klass retain]; _keyPath = [keyPath retain]; } + + [self loadFromObjectCache]; + return self; } @@ -120,28 +146,30 @@ - (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]; - } - } - } - - if (cachedObjects == nil || [cachedObjects count] == 0 || [self needsRefresh]) { - [self load]; - } + 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 {