// // RKObjectPaginator.m // RestKit // // Created by Blake Watters on 12/29/11. // Copyright (c) 2009-2012 RestKit. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //#import "RKObjectPaginator.h" //#import "RKMappingOperation.h" //#import "SOCKit.h" //#import "RKLog.h" // //static NSUInteger RKObjectPaginatorDefaultPerPage = 25; // //// Private interface //@interface RKObjectPaginator () //@property (nonatomic, retain) RKObjectLoader *objectLoader; //@property (nonatomic, assign, readwrite) NSUInteger currentPage; //@property (nonatomic, assign, readwrite) NSUInteger pageCount; //@property (nonatomic, assign, readwrite) NSUInteger objectCount; //@property (nonatomic, assign, readwrite) BOOL loaded; //@end // //@implementation RKObjectPaginator // //@synthesize patternURL = _patternURL; //@synthesize currentPage = _currentPage; //@synthesize perPage = _perPage; //@synthesize loaded = _loaded; //@synthesize pageCount = _pageCount; //@synthesize objectCount = _objectCount; //@synthesize mappingProvider = _mappingProvider; //@synthesize delegate = _delegate; //@synthesize managedObjectStore = _managedObjectStore; //@synthesize objectLoader = _objectLoader; //@synthesize configurationDelegate = _configurationDelegate; //@synthesize onDidLoadObjectsForPage = _onDidLoadObjectsForPage; //@synthesize onDidFailWithError = _onDidFailWithError; // //+ (id)paginatorWithPatternURL:(RKURL *)aPatternURL mappingProvider:(RKObjectMappingProvider *)aMappingProvider //{ // return [[[self alloc] initWithPatternURL:aPatternURL mappingProvider:aMappingProvider] autorelease]; //} // //- (id)initWithPatternURL:(RKURL *)aPatternURL mappingProvider:(RKObjectMappingProvider *)aMappingProvider //{ // self = [super init]; // if (self) { // self.patternURL = [aPatternURL copy]; // self.mappingProvider = [aMappingProvider retain]; // self.currentPage = NSUIntegerMax; // self.pageCount = NSUIntegerMax; // self.objectCount = NSUIntegerMax; // self.perPage = RKObjectPaginatorDefaultPerPage; // self.loaded = NO; // } // // return self; //} // //- (void)dealloc //{ // _delegate = nil; // _configurationDelegate = nil; // _objectLoader.delegate = nil; // [_patternURL release]; // _patternURL = nil; // [_mappingProvider release]; // _mappingProvider = nil; // [_managedObjectStore release]; // _managedObjectStore = nil; // [_objectLoader cancel]; // _objectLoader.delegate = nil; // [_objectLoader release]; // _objectLoader = nil; // [_onDidLoadObjectsForPage release]; // _onDidLoadObjectsForPage = nil; // [_onDidFailWithError release]; // _onDidFailWithError = nil; // // [super dealloc]; //} // //- (RKObjectMapping *)paginationMapping //{ // return [self.mappingProvider paginationMapping]; //} // //- (RKURL *)URL //{ // return [self.patternURL URLByInterpolatingResourcePathWithObject:self]; //} // //// Private. Public consumers can rely on isLoaded //- (BOOL)hasCurrentPage //{ // return _currentPage != NSUIntegerMax; //} // //- (BOOL)hasPageCount //{ // return _pageCount != NSUIntegerMax; //} // //- (BOOL)hasObjectCount //{ // return _objectCount != NSUIntegerMax; //} // //- (NSUInteger)currentPage //{ // // Referenced during initial load, so we don't rely on isLoaded. // NSAssert([self hasCurrentPage], @"Current page has not been initialized."); // return _currentPage; //} // //- (NSUInteger)pageCount //{ // NSAssert([self hasPageCount], @"Page count not available."); // return _pageCount; //} // //- (BOOL)hasNextPage //{ // NSAssert(self.isLoaded, @"Cannot determine hasNextPage: paginator is not loaded."); // NSAssert([self hasPageCount], @"Cannot determine hasNextPage: page count is not known."); // // return self.currentPage < self.pageCount; //} // //- (BOOL)hasPreviousPage //{ // NSAssert(self.isLoaded, @"Cannot determine hasPreviousPage: paginator is not loaded."); // return self.currentPage > 1; //} // //#pragma mark - RKObjectLoaderDelegate methods // //- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects //{ // self.objectLoader = nil; // self.loaded = YES; // RKLogInfo(@"Loaded objects: %@", objects); // [self.delegate paginator:self didLoadObjects:objects forPage:self.currentPage]; // // if (self.onDidLoadObjectsForPage) { // self.onDidLoadObjectsForPage(objects, self.currentPage); // } // // if ([self hasPageCount] && self.currentPage == 1) { // if ([self.delegate respondsToSelector:@selector(paginatorDidLoadFirstPage:)]) { // [self.delegate paginatorDidLoadFirstPage:self]; // } // } // // if ([self hasPageCount] && self.currentPage == self.pageCount) { // if ([self.delegate respondsToSelector:@selector(paginatorDidLoadLastPage:)]) { // [self.delegate paginatorDidLoadLastPage:self]; // } // } //} // //- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error //{ // RKLogError(@"Paginator error %@", error); // [self.delegate paginator:self didFailWithError:error objectLoader:self.objectLoader]; // if (self.onDidFailWithError) { // self.onDidFailWithError(error, self.objectLoader); // } // self.objectLoader = nil; //} // //- (void)objectLoader:(RKObjectLoader *)loader willMapData:(inout id *)mappableData //{ // NSError *error = nil; // RKMappingOperation *mappingOperation = [RKMappingOperation mappingOperationFromObject:*mappableData toObject:self withMapping:[self paginationMapping]]; // BOOL success = [mappingOperation performMapping:&error]; // if (!success) { // self.pageCount = 0; // self.currentPage = 0; // RKLogError(@"Paginator didn't map info to compute page count. Assuming no pages."); // } else if (self.perPage && [self hasObjectCount]) { // float objectCountFloat = self.objectCount; // self.pageCount = ceilf(objectCountFloat / self.perPage); // RKLogInfo(@"Paginator objectCount: %ld pageCount: %ld", (long)self.objectCount, (long)self.pageCount); // } else { // NSAssert(NO, @"Paginator perPage set is 0."); // RKLogError(@"Paginator perPage set is 0."); // } //} // //#pragma mark - Action methods // //- (void)loadNextPage //{ // [self loadPage:self.currentPage + 1]; //} // //- (void)loadPreviousPage //{ // [self loadPage:self.currentPage - 1]; //} // //- (void)loadPage:(NSUInteger)pageNumber //{ // NSAssert(self.mappingProvider, @"Cannot perform a load with a nil mappingProvider."); // NSAssert(! self.objectLoader, @"Cannot perform a load while one is already in progress."); // self.currentPage = pageNumber; // // if (self.managedObjectStore) { // RKManagedObjectLoader *managedObjectLoader = [[[RKManagedObjectLoader alloc] initWithURL:self.URL mappingProvider:self.mappingProvider] autorelease]; // managedObjectLoader.managedObjectContext = self.managedObjectStore.primaryManagedObjectContext; // managedObjectLoader.mainQueueManagedObjectContext = self.managedObjectStore.mainQueueManagedObjectContext; // self.objectLoader = managedObjectLoader; // } else { // self.objectLoader = [[[RKObjectLoader alloc] initWithURL:self.URL mappingProvider:self.mappingProvider] autorelease]; // } // // if ([self.configurationDelegate respondsToSelector:@selector(configureObjectLoader:)]) { // [self.configurationDelegate configureObjectLoader:self.objectLoader]; // } // self.objectLoader.method = RKRequestMethodGET; // self.objectLoader.delegate = self; // // if ([self.delegate respondsToSelector:@selector(paginator:willLoadPage:objectLoader:)]) { // [self.delegate paginator:self willLoadPage:pageNumber objectLoader:self.objectLoader]; // } // // [self.objectLoader send]; //} // //@end