From c69f0118cd07e6010264391318a8749129c6736a Mon Sep 17 00:00:00 2001 From: Blake Watters Date: Tue, 28 Aug 2012 16:08:49 -0400 Subject: [PATCH] Migrate table controller codebase into standalone project --- Code/Support/NSBundle+RKAdditions.h | 26 - Code/Support/NSBundle+RKAdditions.m | 29 - Code/UI/RKAbstractTableController.h | 456 ------ Code/UI/RKAbstractTableController.m | 1446 ----------------- Code/UI/RKAbstractTableController_Internals.h | 78 - Code/UI/RKFetchedResultsTableController.h | 68 - Code/UI/RKFetchedResultsTableController.m | 709 -------- Code/UI/RKKeyboardScroller.h | 57 - Code/UI/RKKeyboardScroller.m | 148 -- Code/UI/RKObjectManager+RKTableController.h | 60 - Code/UI/RKObjectManager+RKTableController.m | 50 - Code/UI/RKRefreshGestureRecognizer.h | 43 - Code/UI/RKRefreshGestureRecognizer.m | 243 --- Code/UI/RKRefreshTriggerView.h | 42 - Code/UI/RKRefreshTriggerView.m | 196 --- Code/UI/RKTableCellBlockTypes.h | 15 - Code/UI/RKTableController.h | 155 -- Code/UI/RKTableController.m | 520 ------ Code/UI/RKTableItem.h | 156 -- Code/UI/RKTableItem.m | 158 -- Code/UI/RKTableSection.h | 59 - Code/UI/RKTableSection.m | 173 -- Code/UI/RKTableViewCellMapping.h | 235 --- Code/UI/RKTableViewCellMapping.m | 295 ---- Code/UI/RKTableViewCellMappings.h | 33 - Code/UI/RKTableViewCellMappings.m | 79 - Code/UI/UI.h | 33 - Code/UI/UIImage+RKAdditions.h | 42 - Code/UI/UIImage+RKAdditions.m | 38 - Code/UI/UIView+FindFirstResponder.h | 27 - Code/UI/UIView+FindFirstResponder.m | 41 - .../RKRefreshTriggerViewAssets/blackArrow.png | Bin 4316 -> 0 bytes .../blackArrow@2x.png | Bin 1616 -> 0 bytes .../RKRefreshTriggerViewAssets/blueArrow.png | Bin 4492 -> 0 bytes .../blueArrow@2x.png | Bin 1529 -> 0 bytes .../RKRefreshTriggerViewAssets/grayArrow.png | Bin 1914 -> 0 bytes .../grayArrow@2x.png | Bin 2109 -> 0 bytes .../RKRefreshTriggerViewAssets/whiteArrow.png | Bin 4180 -> 0 bytes .../whiteArrow@2x.png | Bin 1569 -> 0 bytes RestKit.xcodeproj/project.pbxproj | 124 -- RestKitResources.bundle/Contents/Info.plist | 60 - .../Contents/Resources/blackArrow.png | Bin 4316 -> 0 bytes .../Contents/Resources/blackArrow@2x.png | Bin 1616 -> 0 bytes .../Contents/Resources/blueArrow.png | Bin 4492 -> 0 bytes .../Contents/Resources/blueArrow@2x.png | Bin 1529 -> 0 bytes .../Contents/Resources/grayArrow.png | Bin 1914 -> 0 bytes .../Contents/Resources/grayArrow@2x.png | Bin 2109 -> 0 bytes .../Contents/Resources/whiteArrow.png | Bin 4180 -> 0 bytes .../Contents/Resources/whiteArrow@2x.png | Bin 1569 -> 0 bytes 49 files changed, 5894 deletions(-) delete mode 100755 Code/UI/RKAbstractTableController.h delete mode 100755 Code/UI/RKAbstractTableController.m delete mode 100644 Code/UI/RKAbstractTableController_Internals.h delete mode 100755 Code/UI/RKFetchedResultsTableController.h delete mode 100755 Code/UI/RKFetchedResultsTableController.m delete mode 100644 Code/UI/RKKeyboardScroller.h delete mode 100644 Code/UI/RKKeyboardScroller.m delete mode 100644 Code/UI/RKObjectManager+RKTableController.h delete mode 100644 Code/UI/RKObjectManager+RKTableController.m delete mode 100644 Code/UI/RKRefreshGestureRecognizer.h delete mode 100644 Code/UI/RKRefreshGestureRecognizer.m delete mode 100644 Code/UI/RKRefreshTriggerView.h delete mode 100644 Code/UI/RKRefreshTriggerView.m delete mode 100644 Code/UI/RKTableCellBlockTypes.h delete mode 100644 Code/UI/RKTableController.h delete mode 100644 Code/UI/RKTableController.m delete mode 100644 Code/UI/RKTableItem.h delete mode 100644 Code/UI/RKTableItem.m delete mode 100644 Code/UI/RKTableSection.h delete mode 100644 Code/UI/RKTableSection.m delete mode 100644 Code/UI/RKTableViewCellMapping.h delete mode 100644 Code/UI/RKTableViewCellMapping.m delete mode 100644 Code/UI/RKTableViewCellMappings.h delete mode 100644 Code/UI/RKTableViewCellMappings.m delete mode 100644 Code/UI/UI.h delete mode 100644 Code/UI/UIImage+RKAdditions.h delete mode 100644 Code/UI/UIImage+RKAdditions.m delete mode 100644 Code/UI/UIView+FindFirstResponder.h delete mode 100644 Code/UI/UIView+FindFirstResponder.m delete mode 100644 Resources/RKRefreshTriggerViewAssets/blackArrow.png delete mode 100644 Resources/RKRefreshTriggerViewAssets/blackArrow@2x.png delete mode 100644 Resources/RKRefreshTriggerViewAssets/blueArrow.png delete mode 100644 Resources/RKRefreshTriggerViewAssets/blueArrow@2x.png delete mode 100644 Resources/RKRefreshTriggerViewAssets/grayArrow.png delete mode 100644 Resources/RKRefreshTriggerViewAssets/grayArrow@2x.png delete mode 100644 Resources/RKRefreshTriggerViewAssets/whiteArrow.png delete mode 100644 Resources/RKRefreshTriggerViewAssets/whiteArrow@2x.png delete mode 100644 RestKitResources.bundle/Contents/Info.plist delete mode 100644 RestKitResources.bundle/Contents/Resources/blackArrow.png delete mode 100644 RestKitResources.bundle/Contents/Resources/blackArrow@2x.png delete mode 100644 RestKitResources.bundle/Contents/Resources/blueArrow.png delete mode 100644 RestKitResources.bundle/Contents/Resources/blueArrow@2x.png delete mode 100644 RestKitResources.bundle/Contents/Resources/grayArrow.png delete mode 100644 RestKitResources.bundle/Contents/Resources/grayArrow@2x.png delete mode 100644 RestKitResources.bundle/Contents/Resources/whiteArrow.png delete mode 100644 RestKitResources.bundle/Contents/Resources/whiteArrow@2x.png diff --git a/Code/Support/NSBundle+RKAdditions.h b/Code/Support/NSBundle+RKAdditions.h index 944cd9d46a..7967e82714 100644 --- a/Code/Support/NSBundle+RKAdditions.h +++ b/Code/Support/NSBundle+RKAdditions.h @@ -20,27 +20,12 @@ #import -#if TARGET_OS_IPHONE -#import -#endif - /** Provides convenience methods for accessing data in resources within an NSBundle. */ @interface NSBundle (RKAdditions) -/** - Returns an NSBundle reference to the RestKitResources.bundle file containing - RestKit specific resource assets. - - This method is a convenience wrapper for invoking - `[NSBundle bundleWithIdentifier:@"org.restkit.RestKitResources"]` - - @return An NSBundle object corresponding to the RestKitResources.bundle file. - */ -+ (NSBundle *)restKitResourcesBundle; - /** Returns the MIME Type for the resource identified by the specified name and file extension. @@ -69,17 +54,6 @@ */ - (NSString *)stringWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension encoding:(NSStringEncoding)encoding; -#if TARGET_OS_IPHONE -/** - Creates and returns an image object by loading the image data from the resource identified by the specified name and file extension. - - @param name The name of the resource file. - @param extension If extension is an empty string or nil, the extension is assumed not to exist and the file is the first file encountered that exactly matches name. - @return A new image object for the specified file, or nil if the method could not initialize the image from the specified file. - */ -- (UIImage *)imageWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension; -#endif - /** Creates and returns an object representation of the data from the resource identified by the specified name and file extension by reading the data as a string and parsing it using a parser appropriate for the MIME Type of the file. diff --git a/Code/Support/NSBundle+RKAdditions.m b/Code/Support/NSBundle+RKAdditions.m index 7a130faf28..d3031ecd7f 100644 --- a/Code/Support/NSBundle+RKAdditions.m +++ b/Code/Support/NSBundle+RKAdditions.m @@ -20,28 +20,12 @@ #import "NSBundle+RKAdditions.h" #import "NSString+RKAdditions.h" -#import "UIImage+RKAdditions.h" #import "RKLog.h" #import "RKParser.h" #import "RKParserRegistry.h" @implementation NSBundle (RKAdditions) -+ (NSBundle *)restKitResourcesBundle -{ - static BOOL searchedForBundle = NO; - - if (! searchedForBundle) { - NSString *path = [[NSBundle mainBundle] pathForResource:@"RestKitResources" ofType:@"bundle"]; - searchedForBundle = YES; - NSBundle *resourcesBundle = [NSBundle bundleWithPath:path]; - if (! resourcesBundle) RKLogWarning(@"Unable to find RestKitResources.bundle in your project. Did you forget to add it?"); - return resourcesBundle; - } - - return [NSBundle bundleWithIdentifier:@"org.restkit.RestKitResources"]; -} - - (NSString *)MIMETypeForResource:(NSString *)name withExtension:(NSString *)extension { NSString *resourcePath = [self pathForResource:name ofType:extension]; @@ -80,19 +64,6 @@ - (NSString *)stringWithContentsOfResource:(NSString *)name withExtension:(NSStr return fixtureData; } -#if TARGET_OS_IPHONE -- (UIImage *)imageWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension -{ - NSString *resourcePath = [self pathForResource:name ofType:extension]; - if (! resourcePath) { - RKLogWarning(@"%@ Failed to locate Resource with name '%@' and extension '%@': File Not Found.", self, resourcePath, extension); - return nil; - } - - return [UIImage imageWithContentsOfResolutionIndependentFile:resourcePath]; -} -#endif - - (id)parsedObjectWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension { NSError *error = nil; diff --git a/Code/UI/RKAbstractTableController.h b/Code/UI/RKAbstractTableController.h deleted file mode 100755 index f08578b872..0000000000 --- a/Code/UI/RKAbstractTableController.h +++ /dev/null @@ -1,456 +0,0 @@ -// -// RKAbstractTableController.h -// RestKit -// -// Created by Jeff Arena on 8/11/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. -// - -#if TARGET_OS_IPHONE - -#import -#import "RKTableCellBlockTypes.h" -#import "RKTableViewCellMappings.h" -#import "RKTableItem.h" -#import "RKObjectManager.h" -#import "RKObjectMapping.h" -#import "RKObjectLoader.h" -#import "RKKeyboardScroller.h" - -///----------------------------------------------------------------------------- -/// @name Constants -///----------------------------------------------------------------------------- - -/** - Posted when the table controller starts loading. - */ -extern NSString * const RKTableControllerDidStartLoadNotification; - -/** - Posted when the table controller finishes loading. - */ -extern NSString * const RKTableControllerDidFinishLoadNotification; - -/** - Posted when the table controller has loaded objects into the table view. - */ -extern NSString * const RKTableControllerDidLoadObjectsNotification; - -/** - Posted when the table controller has loaded an empty collection of objects into the table view. - */ -extern NSString * const RKTableControllerDidLoadEmptyNotification; - -/** - Posted when the table controller has loaded an error. - */ -extern NSString * const RKTableControllerDidLoadErrorNotification; - -/** - Posted when the table controller has transitioned from an offline to online state. - */ -extern NSString * const RKTableControllerDidBecomeOnline; - -/** - Posted when the table controller has transitioned from an online to an offline state. - */ -extern NSString * const RKTableControllerDidBecomeOffline; - -@protocol RKAbstractTableControllerDelegate; - -/** - @enum RKTableControllerState - - @constant RKTableControllerStateNormal Indicates that the table has - loaded normally and is displaying cell content. It is not loading content, - is not empty, has not loaded an error, and is not offline. - - @constant RKTableControllerStateLoading Indicates that the table controller - is loading content from a remote source. - - @constant RKTableControllerStateEmpty Indicates that the table controller has - retrieved an empty collection of objects. - - @constant RKTableControllerStateError Indicates that the table controller has - encountered an error while attempting to load. - - @constant RKTableControllerStateOffline Indicates that the table controller is - offline and cannot perform network access. - - @constant RKTableControllerStateNotYetLoaded Indicates that the table controller is - has not yet attempted a load and state is unknown. - */ -enum { - RKTableControllerStateNormal = 0, - RKTableControllerStateLoading = 1 << 1, - RKTableControllerStateEmpty = 1 << 2, - RKTableControllerStateError = 1 << 3, - RKTableControllerStateOffline = 1 << 4, - RKTableControllerStateNotYetLoaded = 0xFF000000 -}; -typedef NSUInteger RKTableControllerState; - -/** - RKAbstractTableController is an abstract base class for concrete table controller classes. - A table controller object acts as both the delegate and data source for a UITableView - object and leverages the RestKit object mapping engine to transform local domain models - into UITableViewCell representations. Concrete implementations are provided for the - display of static table views and Core Data backed fetched results controller basied - table views. - */ -@interface RKAbstractTableController : NSObject - -///----------------------------------------------------------------------------- -/// @name Configuring the Table Controller -///----------------------------------------------------------------------------- - -@property (nonatomic, assign) id delegate; -@property (nonatomic, readonly) UIViewController *viewController; -@property (nonatomic, readonly) UITableView *tableView; -@property (nonatomic, assign) UITableViewRowAnimation defaultRowAnimation; - -@property (nonatomic, assign) BOOL pullToRefreshEnabled; -@property (nonatomic, assign) BOOL canEditRows; -@property (nonatomic, assign) BOOL canMoveRows; -@property (nonatomic, assign) BOOL autoResizesForKeyboard; - -///----------------------------------------------------------------------------- -/// @name Instantiation -///----------------------------------------------------------------------------- - -+ (id)tableControllerWithTableView:(UITableView *)tableView - forViewController:(UIViewController *)viewController; - -+ (id)tableControllerForTableViewController:(UITableViewController *)tableViewController; - -- (id)initWithTableView:(UITableView *)tableView - viewController:(UIViewController *)viewController; - -///----------------------------------------------------------------------------- -/// @name Object to Table View Cell Mappings -///----------------------------------------------------------------------------- - -@property (nonatomic, retain) RKTableViewCellMappings *cellMappings; - -- (void)mapObjectsWithClass:(Class)objectClass toTableCellsWithMapping:(RKTableViewCellMapping *)cellMapping; -- (void)mapObjectsWithClassName:(NSString *)objectClassName toTableCellsWithMapping:(RKTableViewCellMapping *)cellMapping; -- (id)objectForRowAtIndexPath:(NSIndexPath *)indexPath; -- (RKTableViewCellMapping *)cellMappingForObjectAtIndexPath:(NSIndexPath *)indexPath; - -/** - Return the index path of the object within the table - */ -- (NSIndexPath *)indexPathForObject:(id)object; -- (UITableViewCell *)cellForObject:(id)object; -- (void)reloadRowForObject:(id)object withRowAnimation:(UITableViewRowAnimation)rowAnimation; - -///----------------------------------------------------------------------------- -/// @name Header and Footer Rows -///----------------------------------------------------------------------------- - -- (void)addHeaderRowForItem:(RKTableItem *)tableItem; -- (void)addFooterRowForItem:(RKTableItem *)tableItem; -- (void)addHeaderRowWithMapping:(RKTableViewCellMapping *)cellMapping; -- (void)addFooterRowWithMapping:(RKTableViewCellMapping *)cellMapping; -- (void)removeAllHeaderRows; -- (void)removeAllFooterRows; - -///----------------------------------------------------------------------------- -/// @name RESTful Table Loading -///----------------------------------------------------------------------------- - -/** - The object manager instance this table controller is associated with. - - This instance is used for creating object loaders when loading Network - tables and provides the managed object store used for Core Data tables. - Online/offline state is also determined by watching for reachability - notifications generated from the object manager. - - **Default**: The shared manager instance `[RKObjectManager sharedManager]` - */ -@property (nonatomic, assign) RKObjectManager *objectManager; -@property (nonatomic, assign) BOOL autoRefreshFromNetwork; -@property (nonatomic, assign) NSTimeInterval autoRefreshRate; - -- (void)loadTableWithObjectLoader:(RKObjectLoader *)objectLoader; -- (void)cancelLoad; -- (BOOL)isAutoRefreshNeeded; - -///----------------------------------------------------------------------------- -/// @name Inspecting Table State -///----------------------------------------------------------------------------- - -/** - The current state of the table controller. Note that the controller may be in more - than one state (e.g. loading | empty). - */ -@property (nonatomic, readonly, assign) RKTableControllerState state; - -/** - An error object that was encountered as the result of an attempt to load - the table. Will return a value when the table is in the error state, - otherwise nil. - */ -@property (nonatomic, readonly, retain) NSError *error; - -/** - Returns a Boolean value indicating if the table controller is currently - loading content. - */ -- (BOOL)isLoading; - -/** - Returns a Boolean value indicating if the table controller has attempted - a load and transitioned into any state. - */ -- (BOOL)isLoaded; - -/** - Returns a Boolean value indicating if the table controller has loaded an - empty set of content. - - When YES and there is not an empty item configured, the table controller - will optionally display an empty image overlayed on top of the table view. - - **NOTE**: It is possible for an empty table controller to display cells - witin the managed table view in the event an empty item or header/footer - rows are configured. - - @see imageForEmpty - */ -- (BOOL)isEmpty; - -/** - Returns a Boolean value indicating if the table controller is online - and network operations may be performed. - */ -- (BOOL)isOnline; - -/** - Returns a Boolean value indicating if the table controller is offline. - - When YES, the table controller will optionally display an offline image - overlayed on top of the table view. - - @see imageForOffline - */ -- (BOOL)isOffline; - -/** - Returns a Boolean value indicating if the table controller encountered - an error while attempting to load. - - When YES, the table controller will optionally display an error image - overlayed on top of the table view. - - @see imageForError - */ -- (BOOL)isError; - -///----------------------------------------------------------------------------- -/// @name Block Callbacks -///----------------------------------------------------------------------------- - -// TODO: Audit and expand the library of callbacks... -// TODO: Docs AND tests... -@property (nonatomic, copy) RKTableCellForObjectAtIndexPathBlock onSelectCellForObjectAtIndexPath; -@property (nonatomic, copy) RKTableCellForObjectAtIndexPathBlock onPrepareCellForObjectAtIndexPath; // TODO: May want to eliminate... -@property (nonatomic, copy) RKTableCellForObjectAtIndexPathBlock onWillDisplayCellForObjectAtIndexPath; - -- (void)setOnSelectCellForObjectAtIndexPath:(RKTableCellForObjectAtIndexPathBlock)onSelectCellForObjectAtIndexPath; -- (void)setOnPrepareCellForObjectAtIndexPath:(RKTableCellForObjectAtIndexPathBlock)onPrepareCellForObjectAtIndexPath; -- (void)setOnWillDisplayCellForObjectAtIndexPath:(RKTableCellForObjectAtIndexPathBlock)onWillDisplayCellForObjectAtIndexPath; - -///----------------------------------------------------------------------------- -/// @name Model State Views -///----------------------------------------------------------------------------- - -/** - An image to overlay onto the table when the table view - does not have any row data to display. It will be centered - within the table view. - */ -@property (nonatomic, retain) UIImage *imageForEmpty; - -/** - An image to overlay onto the table when a load operation - has encountered an error. It will be centered - within the table view. - */ -@property (nonatomic, retain) UIImage *imageForError; - -/** - An image to overlay onto the table with when the user does - not have connectivity to the Internet. - - @see RKReachabilityObserver - */ -@property (nonatomic, retain) UIImage *imageForOffline; - -/** - A UIView to add to the table overlay during loading. It - will be positioned directly in the center of the table view. - - The loading view is always presented non-modally. - */ -@property (nonatomic, retain) UIView *loadingView; - -/** - Returns the image, if any, configured for display when the table controller - is in the given state. - - **NOTE** This method accepts a single state value. - - @param state The table controller state - @return The image for the specified state, else nil. Always returns nil for - RKTableControllerStateNormal, RKTableControllerStateLoading and RKTableControllerStateLoading. - */ -- (UIImage *)imageForState:(RKTableControllerState)state; - -/** - A rectangle configuring the dimensions for the overlay view that is - applied to the table view during display of the loading view and - state overlay images (offline/error/empty). By default, the overlay - view will be auto-sized to cover the entire table. This can result in - an inaccessible table UI if you have embedded controls within the header - or footer views of your table. You can adjust the frame of the overlay - precisely by configuring the overlayFrame property. - */ -@property (nonatomic, assign) CGRect overlayFrame; - -/** - The image currently displayed within the overlay view. - */ -@property (nonatomic, readonly) UIImage *overlayImage; - -/** - When YES, the image view added to the table overlay for displaying table - state (i.e. for offline, error and empty) will be displayed modally - and prevent any interaction with the table. - - **Default**: YES - */ -@property (nonatomic, assign) BOOL showsOverlayImagesModally; - -// Default NO -@property (nonatomic, assign) BOOL variableHeightRows; -@property (nonatomic, assign) BOOL showsHeaderRowsWhenEmpty; -@property (nonatomic, assign) BOOL showsFooterRowsWhenEmpty; -@property (nonatomic, retain) RKTableItem *emptyItem; - -///----------------------------------------------------------------------------- -/// @name Managing Sections -///----------------------------------------------------------------------------- - -/** - The number of sections in the table. - */ -@property (nonatomic, readonly) NSUInteger sectionCount; - -/** - The number of rows across all sections in the model. - */ -@property (nonatomic, readonly) NSUInteger rowCount; - -/** - Returns the number of rows in the section at the given index. - - @param index The index of the section to return the row count for. - @returns The number of rows contained within the section with the given index. - @raises NSInvalidArgumentException Raised if index is greater than or - equal to the total number of sections in the table. - */ -- (NSUInteger)numberOfRowsInSection:(NSUInteger)index; - -///----------------------------------------------------------------------------- -/// @name Managing Swipe View -///----------------------------------------------------------------------------- - -@property (nonatomic, assign) BOOL cellSwipeViewsEnabled; -@property (nonatomic, retain) UIView *cellSwipeView; -@property (nonatomic, readonly) UITableViewCell *swipeCell; -@property (nonatomic, readonly) id swipeObject; -@property (nonatomic, readonly) BOOL animatingCellSwipe; -@property (nonatomic, readonly) UISwipeGestureRecognizerDirection swipeDirection; - -- (void)addSwipeViewTo:(UITableViewCell *)cell withObject:(id)object direction:(UISwipeGestureRecognizerDirection)direction; -- (void)removeSwipeView:(BOOL)animated; - -@end - -@protocol RKAbstractTableControllerDelegate - -@optional - -// Network -- (void)tableController:(RKAbstractTableController *)tableController willLoadTableWithObjectLoader:(RKObjectLoader *)objectLoader; -- (void)tableController:(RKAbstractTableController *)tableController didLoadTableWithObjectLoader:(RKObjectLoader *)objectLoader; - -// Basic States -- (void)tableControllerDidStartLoad:(RKAbstractTableController *)tableController; - -/** - Sent when the table view has transitioned out of the loading state regardless of outcome - */ -- (void)tableControllerDidFinishLoad:(RKAbstractTableController *)tableController; -- (void)tableController:(RKAbstractTableController *)tableController didFailLoadWithError:(NSError *)error; -- (void)tableControllerDidCancelLoad:(RKAbstractTableController *)tableController; - -/** - Sent to the delegate when the controller is really and truly finished loading/updating, whether from the network or from Core Data, - or from static data, ... this happens in didFinishLoading - */ -- (void)tableControllerDidFinalizeLoad:(RKAbstractTableController *)tableController; - -/** - Sent to the delegate when the content of the table view has become empty - */ -- (void)tableControllerDidBecomeEmpty:(RKAbstractTableController *)tableController; - -/** - Sent to the delegate when the table controller has transitioned from offline to online - */ -- (void)tableControllerDidBecomeOnline:(RKAbstractTableController *)tableController; - -/** - Sent to the delegate when the table controller has transitioned from online to offline - */ -- (void)tableControllerDidBecomeOffline:(RKAbstractTableController *)tableController; - -// Objects -- (void)tableController:(RKAbstractTableController *)tableController didInsertObject:(id)object atIndexPath:(NSIndexPath *)indexPath; -- (void)tableController:(RKAbstractTableController *)tableController didUpdateObject:(id)object atIndexPath:(NSIndexPath *)indexPath; -- (void)tableController:(RKAbstractTableController *)tableController didDeleteObject:(id)object atIndexPath:(NSIndexPath *)indexPath; - -// Editing -- (void)tableController:(RKAbstractTableController *)tableController willBeginEditing:(id)object atIndexPath:(NSIndexPath *)indexPath; -- (void)tableController:(RKAbstractTableController *)tableController didEndEditing:(id)object atIndexPath:(NSIndexPath *)indexPath; - -// Swipe Views -- (void)tableController:(RKAbstractTableController *)tableController willAddSwipeView:(UIView *)swipeView toCell:(UITableViewCell *)cell forObject:(id)object; -- (void)tableController:(RKAbstractTableController *)tableController willRemoveSwipeView:(UIView *)swipeView fromCell:(UITableViewCell *)cell forObject:(id)object; - -// Cells -- (void)tableController:(RKAbstractTableController *)tableController willDisplayCell:(UITableViewCell *)cell forObject:(id)object atIndexPath:(NSIndexPath *)indexPath; -- (void)tableController:(RKAbstractTableController *)tableController didSelectCell:(UITableViewCell *)cell forObject:(id)object atIndexPath:(NSIndexPath *)indexPath; - -// Sections -- (CGFloat)tableController:(RKAbstractTableController *)tableController heightForHeaderInSection:(NSInteger)sectionIndex; -- (CGFloat)tableController:(RKAbstractTableController *)tableController heightForFooterInSection:(NSInteger)sectionIndex; - -@end - -#endif // TARGET_OS_IPHONE diff --git a/Code/UI/RKAbstractTableController.m b/Code/UI/RKAbstractTableController.m deleted file mode 100755 index 185deab7c0..0000000000 --- a/Code/UI/RKAbstractTableController.m +++ /dev/null @@ -1,1446 +0,0 @@ -// -// RKAbstractTableController.m -// RestKit -// -// Created by Jeff Arena on 8/11/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 "RKAbstractTableController.h" -#import "RKAbstractTableController_Internals.h" -#import "RKMappingOperation.h" -#import "RKLog.h" -#import "RKErrors.h" -#import "RKReachabilityObserver.h" -#import "UIView+FindFirstResponder.h" -#import "RKRefreshGestureRecognizer.h" -#import "RKTableSection.h" - -// Define logging component -#undef RKLogComponent -#define RKLogComponent lcl_cRestKitUI - -/** - Bounce pixels define how many pixels the cell swipe view is - moved during the bounce animation - */ -#define BOUNCE_PIXELS 5.0 - -NSString * const RKTableControllerDidStartLoadNotification = @"RKTableControllerDidStartLoadNotification"; -NSString * const RKTableControllerDidFinishLoadNotification = @"RKTableControllerDidFinishLoadNotification"; -NSString * const RKTableControllerDidLoadObjectsNotification = @"RKTableControllerDidLoadObjectsNotification"; -NSString * const RKTableControllerDidLoadEmptyNotification = @"RKTableControllerDidLoadEmptyNotification"; -NSString * const RKTableControllerDidLoadErrorNotification = @"RKTableControllerDidLoadErrorNotification"; -NSString * const RKTableControllerDidBecomeOnline = @"RKTableControllerDidBecomeOnline"; -NSString * const RKTableControllerDidBecomeOffline = @"RKTableControllerDidBecomeOffline"; - -static NSString *lastUpdatedDateDictionaryKey = @"lastUpdatedDateDictionaryKey"; - -@interface RKAbstractTableController () - -@property (nonatomic, retain) RKKeyboardScroller *keyboardScroller; - -@end - - -@implementation RKAbstractTableController - -@synthesize delegate = _delegate; -@synthesize viewController = _viewController; -@synthesize tableView = _tableView; -@synthesize defaultRowAnimation = _defaultRowAnimation; - -@synthesize objectLoader = _objectLoader; -@synthesize objectManager = _objectManager; -@synthesize cellMappings = _cellMappings; -@synthesize autoRefreshFromNetwork = _autoRefreshFromNetwork; -@synthesize autoRefreshRate = _autoRefreshRate; - -@synthesize state = _state; -@synthesize error = _error; - -@synthesize imageForEmpty = _imageForEmpty; -@synthesize imageForError = _imageForError; -@synthesize imageForOffline = _imageForOffline; -@synthesize loadingView = _loadingView; - -@synthesize variableHeightRows = _variableHeightRows; -@synthesize showsHeaderRowsWhenEmpty = _showsHeaderRowsWhenEmpty; -@synthesize showsFooterRowsWhenEmpty = _showsFooterRowsWhenEmpty; -@synthesize pullToRefreshEnabled = _pullToRefreshEnabled; -@synthesize headerItems = _headerItems; -@synthesize footerItems = _footerItems; -@synthesize canEditRows = _canEditRows; -@synthesize canMoveRows = _canMoveRows; -@synthesize autoResizesForKeyboard = _autoResizesForKeyboard; -@synthesize emptyItem = _emptyItem; - -@synthesize onSelectCellForObjectAtIndexPath = _onSelectCellForObjectAtIndexPath; -@synthesize onPrepareCellForObjectAtIndexPath = _onPrepareCellForObjectAtIndexPath; -@synthesize onWillDisplayCellForObjectAtIndexPath = _onWillDisplayCellForObjectAtIndexPath; - -@synthesize cellSwipeViewsEnabled = _cellSwipeViewsEnabled; -@synthesize cellSwipeView = _cellSwipeView; -@synthesize swipeCell = _swipeCell; -@synthesize animatingCellSwipe = _animatingCellSwipe; -@synthesize swipeDirection = _swipeDirection; -@synthesize swipeObject = _swipeObject; - -@synthesize showsOverlayImagesModally = _modalOverlay; -@synthesize overlayFrame = _overlayFrame; -@synthesize tableOverlayView = _tableOverlayView; -@synthesize stateOverlayImageView = _stateOverlayImageView; -@synthesize cache = _cache; -@synthesize pullToRefreshHeaderView = _pullToRefreshHeaderView; - -@synthesize keyboardScroller = _keyboardScroller; - -#pragma mark - Instantiation - -+ (id)tableControllerWithTableView:(UITableView *)tableView - forViewController:(UIViewController *)viewController -{ - return [[[self alloc] initWithTableView:tableView viewController:viewController] autorelease]; -} - -+ (id)tableControllerForTableViewController:(UITableViewController *)tableViewController -{ - return [self tableControllerWithTableView:tableViewController.tableView - forViewController:tableViewController]; -} - -- (id)initWithTableView:(UITableView *)theTableView viewController:(UIViewController *)theViewController -{ - NSAssert(theTableView, @"Cannot initialize a table view model with a nil tableView"); - NSAssert(theViewController, @"Cannot initialize a table view model with a nil viewController"); - self = [self init]; - if (self) { - self.tableView = theTableView; - _viewController = theViewController; // Assign directly to avoid side-effect of overloaded accessor method - self.variableHeightRows = NO; - self.defaultRowAnimation = UITableViewRowAnimationFade; - self.overlayFrame = CGRectZero; - self.showsOverlayImagesModally = YES; - } - - return self; -} - -- (id)init -{ - self = [super init]; - if (self) { - if ([self isMemberOfClass:[RKAbstractTableController class]]) { - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:[NSString stringWithFormat:@"%@ is abstract. Instantiate one its subclasses instead.", - NSStringFromClass([self class])] - userInfo:nil]; - } - - self.state = RKTableControllerStateNotYetLoaded; - self.objectManager = [RKObjectManager sharedManager]; - _cellMappings = [RKTableViewCellMappings new]; - - _headerItems = [NSMutableArray new]; - _footerItems = [NSMutableArray new]; - _showsHeaderRowsWhenEmpty = YES; - _showsFooterRowsWhenEmpty = YES; - - // Setup autoRefreshRate to (effectively) never - _autoRefreshFromNetwork = NO; - _autoRefreshRate = NSTimeIntervalSince1970; - - // Setup key-value observing - [self addObserver:self - forKeyPath:@"state" - options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld - context:nil]; - [self addObserver:self - forKeyPath:@"error" - options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld - context:nil]; - } - return self; -} - -- (void)dealloc -{ - // Disconnect from the tableView - if (_tableView.delegate == self) _tableView.delegate = nil; - if (_tableView.dataSource == self) _tableView.dataSource = nil; - _tableView = nil; - - // Remove overlay and pull-to-refresh subviews - [_stateOverlayImageView removeFromSuperview]; - [_stateOverlayImageView release]; - _stateOverlayImageView = nil; - [_tableOverlayView removeFromSuperview]; - [_tableOverlayView release]; - _tableOverlayView = nil; - - // Remove observers - [self removeObserver:self forKeyPath:@"state"]; - [self removeObserver:self forKeyPath:@"error"]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - // TODO: WTF? Get UI crashes when enabled... -// [_objectManager.requestQueue abortRequestsWithDelegate:self]; - _objectLoader.delegate = nil; - [_objectLoader release]; - _objectLoader = nil; - - // Blocks - [_onSelectCellForObjectAtIndexPath release]; - [_onPrepareCellForObjectAtIndexPath release]; - [_onWillDisplayCellForObjectAtIndexPath release]; - - [_cellMappings release]; - [_headerItems release]; - [_footerItems release]; - [_cellSwipeView release]; - [_swipeCell release]; - [_swipeObject release]; - [_emptyItem release]; - [super dealloc]; -} - -- (void)setTableView:(UITableView *)tableView -{ - NSAssert(tableView, @"Cannot assign a nil tableView to the model"); - _tableView = tableView; - _tableView.delegate = self; - _tableView.dataSource = self; -} - -- (void)setViewController:(UIViewController *)viewController -{ - if ([viewController isKindOfClass:[UITableViewController class]]) { - self.tableView = [(UITableViewController *)viewController tableView]; - } -} - -- (void)setObjectManager:(RKObjectManager *)objectManager -{ - NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; - - // Remove observers - if (_objectManager) { - [notificationCenter removeObserver:self - name:RKObjectManagerDidBecomeOfflineNotification - object:_objectManager]; - [notificationCenter removeObserver:self - name:RKObjectManagerDidBecomeOnlineNotification - object:_objectManager]; - } - - _objectManager = objectManager; - - if (objectManager) { - // Set observers - [notificationCenter addObserver:self - selector:@selector(objectManagerConnectivityDidChange:) - name:RKObjectManagerDidBecomeOnlineNotification - object:objectManager]; - [notificationCenter addObserver:self - selector:@selector(objectManagerConnectivityDidChange:) - name:RKObjectManagerDidBecomeOfflineNotification - object:objectManager]; - - // Initialize online/offline state (if it is known) - if (objectManager.networkStatus != RKObjectManagerNetworkStatusUnknown) { - if (objectManager.isOnline) { - self.state &= ~RKTableControllerStateOffline; - } else { - self.state |= RKTableControllerStateOffline; - } - } - } -} - -- (void)setAutoResizesForKeyboard:(BOOL)autoResizesForKeyboard -{ - if (_autoResizesForKeyboard != autoResizesForKeyboard) { - _autoResizesForKeyboard = autoResizesForKeyboard; - if (_autoResizesForKeyboard) { - self.keyboardScroller = [[RKKeyboardScroller alloc] initWithViewController:self.viewController scrollView:self.tableView]; - [self.keyboardScroller release]; - } else { - self.keyboardScroller = nil; - } - } -} - -- (void)setAutoRefreshFromNetwork:(BOOL)autoRefreshFromNetwork -{ - if (_autoRefreshFromNetwork != autoRefreshFromNetwork) { - _autoRefreshFromNetwork = autoRefreshFromNetwork; - if (_autoRefreshFromNetwork) { - NSString *cachePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] - stringByAppendingPathComponent:@"RKAbstractTableControllerCache"]; - _cache = [[RKCache alloc] initWithPath:cachePath subDirectories:nil]; - } else { - if (_cache) { - [_cache invalidateAll]; - [_cache release]; - _cache = nil; - } - } - } -} - -- (void)setLoading:(BOOL)loading -{ - if (loading) { - self.state |= RKTableControllerStateLoading; - } else { - self.state &= ~RKTableControllerStateLoading; - } -} - -// NOTE: The loaded flag is handled specially. When loaded becomes NO, -// we clear all other flags. In practice this should not happen outside of init. -- (void)setLoaded:(BOOL)loaded -{ - if (loaded) { - self.state &= ~RKTableControllerStateNotYetLoaded; - } else { - self.state = RKTableControllerStateNotYetLoaded; - } -} - -- (void)setEmpty:(BOOL)empty -{ - if (empty) { - self.state |= RKTableControllerStateEmpty; - } else { - self.state &= ~RKTableControllerStateEmpty; - } -} - -- (void)setOffline:(BOOL)offline -{ - if (offline) { - self.state |= RKTableControllerStateOffline; - } else { - self.state &= ~RKTableControllerStateOffline; - } -} - -- (void)setErrorState:(BOOL)error -{ - if (error) { - self.state |= RKTableControllerStateError; - } else { - self.state &= ~RKTableControllerStateError; - } -} - -- (void)objectManagerConnectivityDidChange:(NSNotification *)notification -{ - RKLogTrace(@"%@ received network status change notification: %@", self, [notification name]); - [self setOffline:!self.objectManager.isOnline]; -} - -#pragma mark - Abstract Methods - -- (BOOL)isConsideredEmpty -{ - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)] - userInfo:nil]; -} - -- (NSUInteger)sectionCount -{ - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)] - userInfo:nil]; -} - -- (NSUInteger)rowCount -{ - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)] - userInfo:nil]; -} - -- (id)objectForRowAtIndexPath:(NSIndexPath *)indexPath -{ - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)] - userInfo:nil]; -} - -- (NSIndexPath *)indexPathForObject:(id)object -{ - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)] - userInfo:nil]; -} - -- (NSUInteger)numberOfRowsInSection:(NSUInteger)index -{ - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)] - userInfo:nil]; -} - -#pragma mark - Cell Mappings - -- (void)mapObjectsWithClass:(Class)objectClass toTableCellsWithMapping:(RKTableViewCellMapping *)cellMapping -{ - // TODO: Should we raise an exception/throw a warning if you are doing class mapping for a type - // that implements a cellMapping instance method? Maybe a class declaration overrides - [_cellMappings setCellMapping:cellMapping forClass:objectClass]; -} - -- (void)mapObjectsWithClassName:(NSString *)objectClassName toTableCellsWithMapping:(RKTableViewCellMapping *)cellMapping -{ - [self mapObjectsWithClass:NSClassFromString(objectClassName) toTableCellsWithMapping:cellMapping]; -} - -- (RKTableViewCellMapping *)cellMappingForObjectAtIndexPath:(NSIndexPath *)indexPath -{ - NSAssert(indexPath, @"Cannot lookup cell mapping for object with a nil indexPath"); - id object = [self objectForRowAtIndexPath:indexPath]; - return [self.cellMappings cellMappingForObject:object]; -} - -- (UITableViewCell *)cellForObject:(id)object -{ - NSIndexPath *indexPath = [self indexPathForObject:object]; - return indexPath ? [self.tableView cellForRowAtIndexPath:indexPath] : nil; -} - -#pragma mark - Header and Footer Rows - -- (void)addHeaderRowForItem:(RKTableItem *)tableItem -{ - [_headerItems addObject:tableItem]; -} - -- (void)addFooterRowForItem:(RKTableItem *)tableItem -{ - [_footerItems addObject:tableItem]; -} - -- (void)addHeaderRowWithMapping:(RKTableViewCellMapping *)cellMapping -{ - RKTableItem *tableItem = [RKTableItem tableItem]; - tableItem.cellMapping = cellMapping; - [self addHeaderRowForItem:tableItem]; -} - -- (void)addFooterRowWithMapping:(RKTableViewCellMapping *)cellMapping -{ - RKTableItem *tableItem = [RKTableItem tableItem]; - tableItem.cellMapping = cellMapping; - [self addFooterRowForItem:tableItem]; -} - -- (void)removeAllHeaderRows -{ - [_headerItems removeAllObjects]; -} - -- (void)removeAllFooterRows -{ - [_footerItems removeAllObjects]; -} - -#pragma mark - UITableViewDataSource methods - -- (UITableViewCell *)cellFromCellMapping:(RKTableViewCellMapping *)cellMapping -{ - RKLogTrace(@"About to dequeue reusable cell using self.reuseIdentifier=%@", cellMapping.reuseIdentifier); - UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellMapping.reuseIdentifier]; - if (cell) { - RKLogTrace(@"Dequeued existing cell object for reuse identifier '%@': %@", cellMapping.reuseIdentifier, cell); - } else { - cell = [[[cellMapping.objectClass alloc] initWithStyle:cellMapping.style - reuseIdentifier:cellMapping.reuseIdentifier] autorelease]; - RKLogTrace(@"Failed to dequeue existing cell object for reuse identifier '%@', instantiated new cell: %@", cellMapping.reuseIdentifier, cell); - } - - if (cellMapping.managesCellAttributes) { - cell.accessoryType = cellMapping.accessoryType; - cell.selectionStyle = cellMapping.selectionStyle; - } - - // Fire the prepare callbacks - for (void (^block)(UITableViewCell *) in cellMapping.prepareCellBlocks) { - block(cell); - } - - return cell; -} - -- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSAssert(theTableView == self.tableView, @"tableView:cellForRowAtIndexPath: invoked with inappropriate tableView: %@", theTableView); - NSAssert(indexPath, @"Cannot retrieve cell for nil indexPath"); - id mappableObject = [self objectForRowAtIndexPath:indexPath]; - NSAssert(mappableObject, @"Cannot build a tableView cell without an object"); - - RKTableViewCellMapping* cellMapping = [self.cellMappings cellMappingForObject:mappableObject]; - NSAssert(cellMapping, @"Cannot build a tableView cell for object %@: No cell mapping defined for objects of type '%@'", mappableObject, NSStringFromClass([mappableObject class])); - - UITableViewCell *cell = [self cellFromCellMapping:cellMapping]; - NSAssert(cell, @"Cell mapping failed to dequeue or allocate a tableViewCell for object: %@", mappableObject); - - // Map the object state into the cell - RKMappingOperation* mappingOperation = [[RKMappingOperation alloc] initWithSourceObject:mappableObject destinationObject:cell mapping:cellMapping]; - NSError* error = nil; - BOOL success = [mappingOperation performMapping:&error]; - [mappingOperation release]; - - // NOTE: If there is no mapping work performed, but no error is generated then - // we consider the operation a success. It is common for table cells to not contain - // any dynamically mappable content (i.e. header/footer rows, banners, etc.) - if (success == NO && error != nil) { - RKLogError(@"Failed table cell mapping: %@", error); - } - - if (self.onPrepareCellForObjectAtIndexPath) { - self.onPrepareCellForObjectAtIndexPath(cell, mappableObject, indexPath); - } - - RKLogTrace(@"%@ cellForRowAtIndexPath:%@ = %@", self, indexPath, cell); - return cell; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - [NSException raise:@"Must be implemented in a subclass!" format:@"sectionCount must be implemented with a subclass"]; - return 0; -} - -#pragma mark - UITableViewDelegate methods - -- (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSAssert(theTableView == self.tableView, @"tableView:didSelectRowAtIndexPath: invoked with inappropriate tableView: %@", theTableView); - RKLogTrace(@"%@: Row at indexPath %@ selected for tableView %@", self, indexPath, theTableView); - - id object = [self objectForRowAtIndexPath:indexPath]; - - UITableViewCell *cell = [theTableView cellForRowAtIndexPath:indexPath]; - RKTableViewCellMapping *cellMapping = [_cellMappings cellMappingForObject:object]; - - // NOTE: Handle deselection first as the onSelectCell processing may result in the tableView - // being reloaded and our instances invalidated - if (cellMapping.deselectsRowOnSelection) { - [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; - } - - if (cellMapping.onSelectCell) { - cellMapping.onSelectCell(); - } - - if (cellMapping.onSelectCellForObjectAtIndexPath) { - RKLogTrace(@"%@: Invoking onSelectCellForObjectAtIndexPath block with cellMapping %@ for object %@ at indexPath = %@", self, cell, object, indexPath); - cellMapping.onSelectCellForObjectAtIndexPath(cell, object, indexPath); - } - - // Table level selection callbacks - if (self.onSelectCellForObjectAtIndexPath) { - self.onSelectCellForObjectAtIndexPath(cell, object, indexPath); - } - - if ([self.delegate respondsToSelector:@selector(tableController:didSelectCell:forObject:atIndexPath:)]) { - [self.delegate tableController:self didSelectCell:cell forObject:object atIndexPath:indexPath]; - } -} - -- (void)tableView:(UITableView *)theTableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSAssert(theTableView == self.tableView, @"tableView:didSelectRowAtIndexPath: invoked with inappropriate tableView: %@", theTableView); - cell.hidden = NO; - id mappableObject = [self objectForRowAtIndexPath:indexPath]; - RKTableViewCellMapping *cellMapping = [self.cellMappings cellMappingForObject:mappableObject]; - if (cellMapping.onCellWillAppearForObjectAtIndexPath) { - cellMapping.onCellWillAppearForObjectAtIndexPath(cell, mappableObject, indexPath); - } - - if (self.onWillDisplayCellForObjectAtIndexPath) { - self.onWillDisplayCellForObjectAtIndexPath(cell, mappableObject, indexPath); - } - - if ([self.delegate respondsToSelector:@selector(tableController:willDisplayCell:forObject:atIndexPath:)]) { - [self.delegate tableController:self willDisplayCell:cell forObject:mappableObject atIndexPath:indexPath]; - } - - // Informal protocol - // TODO: Needs documentation!!! - SEL willDisplaySelector = @selector(willDisplayInTableViewCell:); - if ([mappableObject respondsToSelector:willDisplaySelector]) { - [mappableObject performSelector:willDisplaySelector withObject:cell]; - } - - // Handle hiding header/footer rows when empty - if ([self isEmpty]) { - if (! self.showsHeaderRowsWhenEmpty && [_headerItems containsObject:mappableObject]) { - cell.hidden = YES; - } - - if (! self.showsFooterRowsWhenEmpty && [_footerItems containsObject:mappableObject]) { - cell.hidden = YES; - } - } else { - if (self.emptyItem && [self.emptyItem isEqual:mappableObject]) { - cell.hidden = YES; - } - } -} - -// Variable height support - -- (CGFloat)tableView:(UITableView *)theTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath -{ - if (self.variableHeightRows) { - RKTableViewCellMapping *cellMapping = [self cellMappingForObjectAtIndexPath:indexPath]; - - if (cellMapping.heightOfCellForObjectAtIndexPath) { - id object = [self objectForRowAtIndexPath:indexPath]; - CGFloat height = cellMapping.heightOfCellForObjectAtIndexPath(object, indexPath); - RKLogTrace(@"Variable row height configured for tableView. Height via block invocation for row at indexPath '%@' = %f", indexPath, cellMapping.rowHeight); - return height; - } else { - RKLogTrace(@"Variable row height configured for tableView. Height for row at indexPath '%@' = %f", indexPath, cellMapping.rowHeight); - return cellMapping.rowHeight; - } - } - - RKLogTrace(@"Uniform row height configured for tableView. Table view row height = %f", self.tableView.rowHeight); - return self.tableView.rowHeight; -} - -- (void)tableView:(UITableView *)theTableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath -{ - RKTableViewCellMapping *cellMapping = [self cellMappingForObjectAtIndexPath:indexPath]; - if (cellMapping.onTapAccessoryButtonForObjectAtIndexPath) { - RKLogTrace(@"Found a block for tableView:accessoryButtonTappedForRowWithIndexPath: Executing..."); - UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:indexPath]; - id object = [self objectForRowAtIndexPath:indexPath]; - cellMapping.onTapAccessoryButtonForObjectAtIndexPath(cell, object, indexPath); - } -} - -- (NSString *)tableView:(UITableView *)theTableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath -{ - RKTableViewCellMapping *cellMapping = [self cellMappingForObjectAtIndexPath:indexPath]; - if (cellMapping.titleForDeleteButtonForObjectAtIndexPath) { - RKLogTrace(@"Found a block for tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: Executing..."); - UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:indexPath]; - id object = [self objectForRowAtIndexPath:indexPath]; - return cellMapping.titleForDeleteButtonForObjectAtIndexPath(cell, object, indexPath); - } - return NSLocalizedString(@"Delete", nil); -} - -- (UITableViewCellEditingStyle)tableView:(UITableView *)theTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath -{ - if (_canEditRows) { - RKTableViewCellMapping *cellMapping = [self cellMappingForObjectAtIndexPath:indexPath]; - UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:indexPath]; - if (cellMapping.editingStyleForObjectAtIndexPath) { - RKLogTrace(@"Found a block for tableView:editingStyleForRowAtIndexPath: Executing..."); - id object = [self objectForRowAtIndexPath:indexPath]; - return cellMapping.editingStyleForObjectAtIndexPath(cell, object, indexPath); - } - return UITableViewCellEditingStyleDelete; - } - return UITableViewCellEditingStyleNone; -} - -- (void)tableView:(UITableView *)theTableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath -{ - if ([self.delegate respondsToSelector:@selector(tableController:didEndEditing:atIndexPath:)]) { - id object = [self objectForRowAtIndexPath:indexPath]; - [self.delegate tableController:self didEndEditing:object atIndexPath:indexPath]; - } -} - -- (void)tableView:(UITableView *)theTableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath -{ - if ([self.delegate respondsToSelector:@selector(tableController:willBeginEditing:atIndexPath:)]) { - id object = [self objectForRowAtIndexPath:indexPath]; - [self.delegate tableController:self willBeginEditing:object atIndexPath:indexPath]; - } -} - -- (NSIndexPath *)tableView:(UITableView *)theTableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath -{ - if (_canMoveRows) { - RKTableViewCellMapping *cellMapping = [self cellMappingForObjectAtIndexPath:sourceIndexPath]; - if (cellMapping.targetIndexPathForMove) { - RKLogTrace(@"Found a block for tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: Executing..."); - UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:sourceIndexPath]; - id object = [self objectForRowAtIndexPath:sourceIndexPath]; - return cellMapping.targetIndexPathForMove(cell, object, sourceIndexPath, proposedDestinationIndexPath); - } - } - return proposedDestinationIndexPath; -} - -- (NSIndexPath *)tableView:(UITableView *)theTableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - [self removeSwipeView:YES]; - return indexPath; -} - -#pragma mark - Network Table Loading - -- (void)cancelLoad -{ - [self.objectLoader cancel]; -} - -- (NSDate *)lastUpdatedDate -{ - if (! self.objectLoader) { - return nil; - } - - if (_autoRefreshFromNetwork) { - NSAssert(_cache, @"Found a nil cache when trying to read our last loaded time"); - NSDictionary *lastUpdatedDates = [_cache dictionaryForCacheKey:lastUpdatedDateDictionaryKey]; - RKLogTrace(@"Last updated dates dictionary retrieved from tableController cache: %@", lastUpdatedDates); - if (lastUpdatedDates) { - NSString *absoluteURLString = [self.objectLoader.URL absoluteString]; - NSNumber *lastUpdatedTimeIntervalSince1970 = (NSNumber *)[lastUpdatedDates objectForKey:absoluteURLString]; - if (absoluteURLString && lastUpdatedTimeIntervalSince1970) { - return [NSDate dateWithTimeIntervalSince1970:[lastUpdatedTimeIntervalSince1970 doubleValue]]; - } - } - } - return nil; -} - -- (BOOL)isAutoRefreshNeeded -{ - BOOL isAutoRefreshNeeded = NO; - if (_autoRefreshFromNetwork) { - isAutoRefreshNeeded = YES; - NSDate *lastUpdatedDate = [self lastUpdatedDate]; - RKLogTrace(@"Last updated: %@", lastUpdatedDate); - if (lastUpdatedDate) { - RKLogTrace(@"-timeIntervalSinceNow=%f, autoRefreshRate=%f", - -[lastUpdatedDate timeIntervalSinceNow], _autoRefreshRate); - isAutoRefreshNeeded = (-[lastUpdatedDate timeIntervalSinceNow] > _autoRefreshRate); - } - } - return isAutoRefreshNeeded; -} - -#pragma mark - RKRequestDelegate & RKObjectLoaderDelegate methods - -- (void)requestDidStartLoad:(RKRequest *)request -{ - RKLogTrace(@"tableController %@ started loading.", self); - [self didStartLoad]; -} - -- (void)requestDidCancelLoad:(RKRequest *)request -{ - RKLogTrace(@"tableController %@ cancelled loading.", self); - self.loading = NO; - - if ([self.delegate respondsToSelector:@selector(tableControllerDidCancelLoad:)]) { - [self.delegate tableControllerDidCancelLoad:self]; - } -} - -- (void)requestDidTimeout:(RKRequest *)request -{ - RKLogTrace(@"tableController %@ timed out while loading.", self); - self.loading = NO; -} - -- (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response -{ - RKLogTrace(@"tableController %@ finished loading.", self); - - // Updated the lastUpdatedDate dictionary using the URL of the request - if (self.autoRefreshFromNetwork) { - NSAssert(_cache, @"Found a nil cache when trying to save our last loaded time"); - NSMutableDictionary *lastUpdatedDates = [[_cache dictionaryForCacheKey:lastUpdatedDateDictionaryKey] mutableCopy]; - if (lastUpdatedDates) { - [_cache invalidateEntry:lastUpdatedDateDictionaryKey]; - } else { - lastUpdatedDates = [[NSMutableDictionary alloc] init]; - } - NSNumber *timeIntervalSince1970 = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]]; - RKLogTrace(@"Setting timeIntervalSince1970=%@ for URL %@", timeIntervalSince1970, [request.URL absoluteString]); - [lastUpdatedDates setObject:timeIntervalSince1970 - forKey:[request.URL absoluteString]]; - [_cache writeDictionary:lastUpdatedDates withCacheKey:lastUpdatedDateDictionaryKey]; - [lastUpdatedDates release]; - } -} - -- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error -{ - RKLogError(@"tableController %@ failed network load with error: %@", self, error); - [self didFailLoadWithError:error]; -} - -- (void)objectLoaderDidFinishLoading:(RKObjectLoader *)objectLoader -{ - if ([self.delegate respondsToSelector:@selector(tableController:didLoadTableWithObjectLoader:)]) { - [self.delegate tableController:self didLoadTableWithObjectLoader:objectLoader]; - } - - [objectLoader reset]; - [self didFinishLoad]; -} - -- (void)didStartLoad -{ - self.loading = YES; -} - -- (void)didFailLoadWithError:(NSError *)error -{ - self.error = error; - [self didFinishLoad]; -} - -- (void)didFinishLoad -{ - self.empty = [self isConsideredEmpty]; - self.loading = [self.objectLoader isLoading]; // Mutate loading state after we have adjusted empty - self.loaded = YES; - - if (![self isEmpty] && ![self isLoading]) { - [[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidLoadObjectsNotification object:self]; - } - - if (self.delegate && [_delegate respondsToSelector:@selector(tableControllerDidFinalizeLoad:)]) { - [self.delegate performSelector:@selector(tableControllerDidFinalizeLoad:) withObject:self]; - } -} - -#pragma mark - Table Overlay Views - -- (UIImage *)imageForState:(RKTableControllerState)state -{ - switch (state) { - case RKTableControllerStateNormal: - case RKTableControllerStateLoading: - case RKTableControllerStateNotYetLoaded: - break; - - case RKTableControllerStateEmpty: - return self.imageForEmpty; - break; - - case RKTableControllerStateError: - return self.imageForError; - break; - - case RKTableControllerStateOffline: - return self.imageForOffline; - break; - - default: - break; - } - - return nil; -} - -- (UIImage *)overlayImage -{ - return _stateOverlayImageView.image; -} - -// Adds an overlay view above the table -- (void)addToOverlayView:(UIView *)view modally:(BOOL)modally -{ - if (! _tableOverlayView) { - CGRect overlayFrame = CGRectIsEmpty(self.overlayFrame) ? self.tableView.frame : self.overlayFrame; - _tableOverlayView = [[UIView alloc] initWithFrame:overlayFrame]; - _tableOverlayView.autoresizesSubviews = YES; - _tableOverlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin; - NSInteger tableIndex = [_tableView.superview.subviews indexOfObject:_tableView]; - if (tableIndex != NSNotFound) { - [_tableView.superview addSubview:_tableOverlayView]; - } - } - - // When modal, we enable user interaction to catch & discard events on the overlay and its subviews - _tableOverlayView.userInteractionEnabled = modally; - view.userInteractionEnabled = modally; - - if (CGRectIsEmpty(view.frame)) { - view.frame = _tableOverlayView.bounds; - - // Center it in the overlay - view.center = _tableOverlayView.center; - } - - [_tableOverlayView addSubview:view]; -} - -- (void)resetOverlayView -{ - if (_stateOverlayImageView && _stateOverlayImageView.image == nil) { - [_stateOverlayImageView removeFromSuperview]; - } - if (_tableOverlayView && _tableOverlayView.subviews.count == 0) { - [_tableOverlayView removeFromSuperview]; - [_tableOverlayView release]; - _tableOverlayView = nil; - } -} - -- (void)addSubviewOverTableView:(UIView *)view -{ - NSInteger tableIndex = [_tableView.superview.subviews - indexOfObject:_tableView]; - if (NSNotFound != tableIndex) { - [_tableView.superview addSubview:view]; - } -} - -- (BOOL)removeImageFromOverlay:(UIImage *)image -{ - if (image && _stateOverlayImageView.image == image) { - _stateOverlayImageView.image = nil; - return YES; - } - return NO; -} - -- (void)showImageInOverlay:(UIImage *)image -{ - NSAssert(self.tableView, @"Cannot add an overlay image to a nil tableView"); - if (! _stateOverlayImageView) { - _stateOverlayImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; - _stateOverlayImageView.opaque = YES; - _stateOverlayImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin; - _stateOverlayImageView.contentMode = UIViewContentModeCenter; - } - _stateOverlayImageView.image = image; - [self addToOverlayView:_stateOverlayImageView modally:self.showsOverlayImagesModally]; -} - -- (void)removeImageOverlay -{ - _stateOverlayImageView.image = nil; - [_stateOverlayImageView removeFromSuperview]; - [self resetOverlayView]; -} - -- (void)setImageForEmpty:(UIImage *)imageForEmpty -{ - [imageForEmpty retain]; - BOOL imageRemoved = [self removeImageFromOverlay:_imageForEmpty]; - [_imageForEmpty release]; - _imageForEmpty = imageForEmpty; - if (imageRemoved) [self showImageInOverlay:_imageForEmpty]; -} - -- (void)setImageForError:(UIImage *)imageForError -{ - [imageForError retain]; - BOOL imageRemoved = [self removeImageFromOverlay:_imageForError]; - [_imageForError release]; - _imageForError = imageForError; - if (imageRemoved) [self showImageInOverlay:_imageForError]; -} - -- (void)setImageForOffline:(UIImage *)imageForOffline -{ - [imageForOffline retain]; - BOOL imageRemoved = [self removeImageFromOverlay:_imageForOffline]; - [_imageForOffline release]; - _imageForOffline = imageForOffline; - if (imageRemoved) [self showImageInOverlay:_imageForOffline]; -} - -- (void)setLoadingView:(UIView *)loadingView -{ - [loadingView retain]; - BOOL viewRemoved = (_loadingView.superview != nil); - [_loadingView removeFromSuperview]; - [self resetOverlayView]; - [_loadingView release]; - _loadingView = loadingView; - if (viewRemoved) [self addToOverlayView:_loadingView modally:NO]; -} - -#pragma mark - KVO & Table States - -- (BOOL)isLoading -{ - return (self.state & RKTableControllerStateLoading) != 0; -} - -- (BOOL)isLoaded -{ - return (self.state & RKTableControllerStateNotYetLoaded) == 0; -// return self.state != RKTableControllerStateNotYetLoaded; -} - -- (BOOL)isOffline -{ - return (self.state & RKTableControllerStateOffline) != 0; -} -- (BOOL)isOnline -{ - return ![self isOffline]; -} - -- (BOOL)isError -{ - return (self.state & RKTableControllerStateError) != 0; -} - -- (BOOL)isEmpty -{ - return (self.state & RKTableControllerStateEmpty) != 0; -} - -- (void)isLoadingDidChange -{ - if ([self isLoading]) { - if ([self.delegate respondsToSelector:@selector(tableControllerDidStartLoad:)]) { - [self.delegate tableControllerDidStartLoad:self]; - } - - [[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidStartLoadNotification object:self]; - - if (self.loadingView) { - [self addToOverlayView:self.loadingView modally:NO]; - } - } else { - if ([self.delegate respondsToSelector:@selector(tableControllerDidFinishLoad:)]) { - [self.delegate tableControllerDidFinishLoad:self]; - } - - [[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidFinishLoadNotification object:self]; - - if (self.loadingView) { - [self.loadingView removeFromSuperview]; - [self resetOverlayView]; - } - - [self resetPullToRefreshRecognizer]; - } - - // We don't want any image overlays applied until loading is finished - _stateOverlayImageView.hidden = [self isLoading]; -} - -- (void)isLoadedDidChange -{ - if ([self isLoaded]) { - RKLogDebug(@"%@: is now loaded.", self); - } else { - RKLogDebug(@"%@: is NOT loaded.", self); - } -} - -- (void)isErrorDidChange -{ - if ([self isError]) { - if ([self.delegate respondsToSelector:@selector(tableController:didFailLoadWithError:)]) { - [self.delegate tableController:self didFailLoadWithError:self.error]; - } - - NSDictionary *userInfo = [NSDictionary dictionaryWithObject:self.error forKey:RKErrorNotificationErrorKey]; - [[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidLoadErrorNotification object:self userInfo:userInfo]; - } -} - -- (void)isEmptyDidChange -{ - if ([self isEmpty]) { - if ([self.delegate respondsToSelector:@selector(tableControllerDidBecomeEmpty:)]) { - [self.delegate tableControllerDidBecomeEmpty:self]; - } - - [[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidLoadEmptyNotification object:self]; - } -} - -- (void)isOnlineDidChange -{ - if ([self isOnline]) { - // We just transitioned to online - if ([self.delegate respondsToSelector:@selector(tableControllerDidBecomeOnline:)]) { - [self.delegate tableControllerDidBecomeOnline:self]; - } - - [[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidBecomeOnline object:self]; - } else { - // We just transitioned to offline - if ([self.delegate respondsToSelector:@selector(tableControllerDidBecomeOffline:)]) { - [self.delegate tableControllerDidBecomeOffline:self]; - } - - [[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidBecomeOffline object:self]; - } -} - -- (void)updateTableViewForStateChange:(NSDictionary *)change -{ - RKTableControllerState oldState = [[change valueForKey:NSKeyValueChangeOldKey] integerValue]; - RKTableControllerState newState = [[change valueForKey:NSKeyValueChangeNewKey] integerValue]; - - // Determine state transitions - BOOL loadedChanged = ((oldState ^ newState) & RKTableControllerStateNotYetLoaded); - BOOL emptyChanged = ((oldState ^ newState) & RKTableControllerStateEmpty); - BOOL offlineChanged = ((oldState ^ newState) & RKTableControllerStateOffline); - BOOL loadingChanged = ((oldState ^ newState) & RKTableControllerStateLoading); - BOOL errorChanged = ((oldState ^ newState) & RKTableControllerStateError); - - if (loadedChanged) [self isLoadedDidChange]; - if (emptyChanged) [self isEmptyDidChange]; - if (offlineChanged) [self isOnlineDidChange]; - if (errorChanged) [self isErrorDidChange]; - if (loadingChanged) [self isLoadingDidChange]; - - // Clear the image from the overlay - _stateOverlayImageView.image = nil; - - // Determine the appropriate overlay image to display (if any) - if (self.state == RKTableControllerStateNormal) { - [self removeImageOverlay]; - } else { - if ([self isLoading]) { - // During a load we don't adjust the overlay - return; - } - - // Though the table can be in more than one state, we only - // want to display a single overlay image. - if ([self isOffline] && self.imageForOffline) { - [self showImageInOverlay:self.imageForOffline]; - } else if ([self isError] && self.imageForError) { - [self showImageInOverlay:self.imageForError]; - } else if ([self isEmpty] && self.imageForEmpty) { - [self showImageInOverlay:self.imageForEmpty]; - } - } - - // Remove the overlay if no longer in use - [self resetOverlayView]; -} - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ - if ([keyPath isEqualToString:@"state"]) { - [self updateTableViewForStateChange:change]; - } else if ([keyPath isEqualToString:@"error"]) { - [self setErrorState:(self.error != nil)]; - } -} - -#pragma mark - Pull to Refresh - -- (RKRefreshGestureRecognizer *)pullToRefreshGestureRecognizer -{ - RKRefreshGestureRecognizer *refreshRecognizer = nil; - for (RKRefreshGestureRecognizer *recognizer in self.tableView.gestureRecognizers) { - if ([recognizer isKindOfClass:[RKRefreshGestureRecognizer class]]) { - refreshRecognizer = recognizer; - break; - } - } - return refreshRecognizer; -} - -- (void)setPullToRefreshEnabled:(BOOL)pullToRefreshEnabled -{ - RKRefreshGestureRecognizer *recognizer = nil; - if (pullToRefreshEnabled) { - recognizer = [[[RKRefreshGestureRecognizer alloc] initWithTarget:self action:@selector(pullToRefreshStateChanged:)] autorelease]; - [self.tableView addGestureRecognizer:recognizer]; - } - else { - recognizer = [self pullToRefreshGestureRecognizer]; - if (recognizer) - [self.tableView removeGestureRecognizer:recognizer]; - } - _pullToRefreshEnabled = pullToRefreshEnabled; -} - -- (void)pullToRefreshStateChanged:(UIGestureRecognizer *)gesture -{ - if (gesture.state == UIGestureRecognizerStateRecognized) { - if ([self pullToRefreshDataSourceIsLoading:gesture]) - return; - RKLogDebug(@"%@: pull to refresh triggered from gesture: %@", self, gesture); - if (self.objectLoader) { - [self.objectLoader reset]; - [self.objectLoader send]; - } - } -} - -- (void)resetPullToRefreshRecognizer -{ - RKRefreshGestureRecognizer *recognizer = [self pullToRefreshGestureRecognizer]; - if (recognizer) - [recognizer setRefreshState:RKRefreshIdle]; -} - -- (BOOL)pullToRefreshDataSourceIsLoading:(UIGestureRecognizer *)gesture -{ - // If we have already been loaded and we are loading again, a refresh is taking place... - return [self isLoaded] && [self isLoading] && [self isOnline]; -} - -- (NSDate *)pullToRefreshDataSourceLastUpdated:(UIGestureRecognizer *)gesture -{ - NSDate *dataSourceLastUpdated = [self lastUpdatedDate]; - return dataSourceLastUpdated ? dataSourceLastUpdated : [NSDate date]; -} - -#pragma mark - Cell Swipe Menu Methods - -- (void)setupSwipeGestureRecognizers -{ - // Setup a right swipe gesture recognizer - UISwipeGestureRecognizer *rightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRight:)]; - rightSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight; - [self.tableView addGestureRecognizer:rightSwipeGestureRecognizer]; - [rightSwipeGestureRecognizer release]; - - // Setup a left swipe gesture recognizer - UISwipeGestureRecognizer *leftSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft:)]; - leftSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft; - [self.tableView addGestureRecognizer:leftSwipeGestureRecognizer]; - [leftSwipeGestureRecognizer release]; -} - -- (void)removeSwipeGestureRecognizers -{ - for (UIGestureRecognizer *recognizer in self.tableView.gestureRecognizers) { - if ([recognizer isKindOfClass:[UISwipeGestureRecognizer class]]) { - [self.tableView removeGestureRecognizer:recognizer]; - } - } -} - -- (void)setCanEditRows:(BOOL)canEditRows -{ - NSAssert(!_cellSwipeViewsEnabled, @"Table model cannot be made editable when cell swipe menus are enabled"); - _canEditRows = canEditRows; -} - -- (void)setCellSwipeViewsEnabled:(BOOL)cellSwipeViewsEnabled -{ - NSAssert(!_canEditRows, @"Cell swipe menus cannot be enabled for editable tableModels"); - if (cellSwipeViewsEnabled) { - [self setupSwipeGestureRecognizers]; - } else { - [self removeSwipeView:YES]; - [self removeSwipeGestureRecognizers]; - } - _cellSwipeViewsEnabled = cellSwipeViewsEnabled; -} - -- (void)swipe:(UISwipeGestureRecognizer *)recognizer direction:(UISwipeGestureRecognizerDirection)direction -{ - if (_cellSwipeViewsEnabled && recognizer && recognizer.state == UIGestureRecognizerStateEnded) { - CGPoint location = [recognizer locationInView:self.tableView]; - NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location]; - UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; - id object = [self objectForRowAtIndexPath:indexPath]; - - if (cell.frame.origin.x != 0) { - [self removeSwipeView:YES]; - return; - } - - [self removeSwipeView:NO]; - - if (cell != _swipeCell && !_animatingCellSwipe) { - [self addSwipeViewTo:cell withObject:object direction:direction]; - } - } -} - -- (void)swipeLeft:(UISwipeGestureRecognizer *)recognizer -{ - [self swipe:recognizer direction:UISwipeGestureRecognizerDirectionLeft]; -} - -- (void)swipeRight:(UISwipeGestureRecognizer *)recognizer -{ - [self swipe:recognizer direction:UISwipeGestureRecognizerDirectionRight]; -} - -- (void)addSwipeViewTo:(UITableViewCell *)cell withObject:(id)object direction:(UISwipeGestureRecognizerDirection)direction -{ - if (_cellSwipeViewsEnabled) { - NSAssert(cell, @"Cannot process swipe view with nil cell"); - NSAssert(object, @"Cannot process swipe view with nil object"); - - _cellSwipeView.frame = cell.frame; - - if ([self.delegate respondsToSelector:@selector(tableController:willAddSwipeView:toCell:forObject:)]) { - [self.delegate tableController:self - willAddSwipeView:_cellSwipeView - toCell:cell - forObject:object]; - } - - [self.tableView insertSubview:_cellSwipeView belowSubview:cell]; - - _swipeCell = [cell retain]; - _swipeObject = [object retain]; - _swipeDirection = direction; - - CGRect cellFrame = cell.frame; - - _cellSwipeView.frame = CGRectMake(0, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); - - _animatingCellSwipe = YES; - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.2]; - [UIView setAnimationDelegate:self]; - [UIView setAnimationDidStopSelector:@selector(animationDidStopAddingSwipeView:finished:context:)]; - - cell.frame = CGRectMake(direction == UISwipeGestureRecognizerDirectionRight ? cellFrame.size.width : -cellFrame.size.width, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); - [UIView commitAnimations]; - } -} - -- (void)animationDidStopAddingSwipeView:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context -{ - _animatingCellSwipe = NO; -} - -- (void)removeSwipeView:(BOOL)animated -{ - if (!_cellSwipeViewsEnabled || !_swipeCell || _animatingCellSwipe) { - RKLogTrace(@"Exiting early with _cellSwipeViewsEnabled=%d, _swipCell=%@, _animatingCellSwipe=%d", - _cellSwipeViewsEnabled, _swipeCell, _animatingCellSwipe); - return; - } - - if ([self.delegate respondsToSelector:@selector(tableController:willRemoveSwipeView:fromCell:forObject:)]) { - [self.delegate tableController:self - willRemoveSwipeView:_cellSwipeView - fromCell:_swipeCell - forObject:_swipeObject]; - } - - if (animated) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.2]; - if (_swipeDirection == UISwipeGestureRecognizerDirectionRight) { - _swipeCell.frame = CGRectMake(BOUNCE_PIXELS, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height); - } else { - _swipeCell.frame = CGRectMake(-BOUNCE_PIXELS, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height); - } - _animatingCellSwipe = YES; - [UIView setAnimationDelegate:self]; - [UIView setAnimationDidStopSelector:@selector(animationDidStopOne:finished:context:)]; - [UIView commitAnimations]; - } else { - [_cellSwipeView removeFromSuperview]; - _swipeCell.frame = CGRectMake(0, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height); - [_swipeCell release]; - _swipeCell = nil; - } -} - -- (void)animationDidStopOne:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context -{ - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.2]; - if (_swipeDirection == UISwipeGestureRecognizerDirectionRight) { - _swipeCell.frame = CGRectMake(BOUNCE_PIXELS*2, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height); - } else { - _swipeCell.frame = CGRectMake(-BOUNCE_PIXELS*2, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height); - } - [UIView setAnimationDelegate:self]; - [UIView setAnimationDidStopSelector:@selector(animationDidStopTwo:finished:context:)]; - [UIView setAnimationCurve:UIViewAnimationCurveLinear]; - [UIView commitAnimations]; -} - -- (void)animationDidStopTwo:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context -{ - [UIView commitAnimations]; - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.2]; - if (_swipeDirection == UISwipeGestureRecognizerDirectionRight) { - _swipeCell.frame = CGRectMake(0, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height); - } else { - _swipeCell.frame = CGRectMake(0, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height); - } - [UIView setAnimationDelegate:self]; - [UIView setAnimationDidStopSelector:@selector(animationDidStopThree:finished:context:)]; - [UIView setAnimationCurve:UIViewAnimationCurveLinear]; - [UIView commitAnimations]; -} - -- (void)animationDidStopThree:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context -{ - _animatingCellSwipe = NO; - [_swipeCell release]; - _swipeCell = nil; - [_cellSwipeView removeFromSuperview]; -} - -#pragma mark UIScrollViewDelegate methods - -- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView -{ - [self removeSwipeView:YES]; -} - -- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView -{ - [self removeSwipeView:NO]; - return YES; -} - -- (void)loadTableWithObjectLoader:(RKObjectLoader *)objectLoader -{ - NSAssert(objectLoader, @"Cannot perform a network load without an object loader"); - if (! [self.objectLoader isEqual:objectLoader]) { - if (self.objectLoader) { - RKLogDebug(@"Cancelling in progress table load: asked to load with a new object loader."); - [self.objectLoader.queue cancelRequest:self.objectLoader]; - } - - objectLoader.delegate = self; - self.objectLoader = objectLoader; - } - if ([self.delegate respondsToSelector:@selector(tableController:willLoadTableWithObjectLoader:)]) { - [self.delegate tableController:self willLoadTableWithObjectLoader:self.objectLoader]; - } - if (self.objectLoader.queue && ![self.objectLoader.queue containsRequest:self.objectLoader]) { - [self.objectLoader.queue addRequest:self.objectLoader]; - } -} - -- (void)reloadRowForObject:(id)object withRowAnimation:(UITableViewRowAnimation)rowAnimation -{ - NSIndexPath *indexPath = [self indexPathForObject:object]; - if (indexPath) { - [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:rowAnimation]; - } -} - -@end diff --git a/Code/UI/RKAbstractTableController_Internals.h b/Code/UI/RKAbstractTableController_Internals.h deleted file mode 100644 index 4c721f452f..0000000000 --- a/Code/UI/RKAbstractTableController_Internals.h +++ /dev/null @@ -1,78 +0,0 @@ -// -// RKAbstractTableController_Internals.h -// RestKit -// -// Created by Jeff Arena on 8/11/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 -#import "RKRefreshGestureRecognizer.h" - -/* - A private continuation class for subclass implementations of RKAbstractTableController - */ -@interface RKAbstractTableController () - -@property (nonatomic, readwrite, assign) UITableView *tableView; -@property (nonatomic, readwrite, assign) UIViewController *viewController; -@property (nonatomic, assign, readwrite) RKTableControllerState state; -@property (nonatomic, readwrite, retain) RKObjectLoader *objectLoader; -@property (nonatomic, readwrite, retain) NSError *error; -@property (nonatomic, readwrite, retain) NSMutableArray *headerItems; -@property (nonatomic, readwrite, retain) NSMutableArray *footerItems; -@property (nonatomic, readonly) UIView *tableOverlayView; -@property (nonatomic, readonly) UIImageView *stateOverlayImageView; -@property (nonatomic, readonly) RKCache *cache; -@property (nonatomic, retain) UIView *pullToRefreshHeaderView; - -#pragma mark - Subclass Load Event Hooks - -- (void)didStartLoad; - -/** - Must be invoked when the table controller has finished loading. - - Responsible for finalizing loading, empty, and loaded states - and cleaning up the table overlay view. - */ -- (void)didFinishLoad; -- (void)didFailLoadWithError:(NSError *)error; - -#pragma mark - Table View Overlay - -- (void)addToOverlayView:(UIView *)view modally:(BOOL)modally; -- (void)resetOverlayView; -- (void)addSubviewOverTableView:(UIView *)view; -- (BOOL)removeImageFromOverlay:(UIImage *)image; -- (void)showImageInOverlay:(UIImage *)image; -- (void)removeImageOverlay; - -#pragma mark - Pull to Refresh Private Methods - -- (void)pullToRefreshStateChanged:(UIGestureRecognizer *)gesture; -- (void)resetPullToRefreshRecognizer; - -/** - Returns a Boolean value indicating if the table controller - should be considered empty and transitioned into the empty state. - Used by the abstract table controller to trigger state transitions. - - **NOTE**: This is an abstract method that MUST be implemented with - a subclass. - */ -- (BOOL)isConsideredEmpty; - -@end diff --git a/Code/UI/RKFetchedResultsTableController.h b/Code/UI/RKFetchedResultsTableController.h deleted file mode 100755 index 6900bacf01..0000000000 --- a/Code/UI/RKFetchedResultsTableController.h +++ /dev/null @@ -1,68 +0,0 @@ -// -// RKFetchedResultsTableController.h -// RestKit -// -// Created by Blake Watters on 8/2/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 -#import "RKAbstractTableController.h" - -typedef UIView *(^RKFetchedResultsTableViewViewForHeaderInSectionBlock)(NSUInteger sectionIndex, NSString *sectionTitle); - -@class RKFetchedResultsTableController; -@protocol RKFetchedResultsTableControllerDelegate - -@optional - -// Sections -- (void)tableController:(RKFetchedResultsTableController *)tableController didInsertSectionAtIndex:(NSUInteger)sectionIndex; -- (void)tableController:(RKFetchedResultsTableController *)tableController didDeleteSectionAtIndex:(NSUInteger)sectionIndex; - -@end - -/** - Instances of RKFetchedResultsTableController provide an interface for driving a UITableView - */ -@interface RKFetchedResultsTableController : RKAbstractTableController - -// Delegate -@property (nonatomic, assign) id delegate; - -// Fetched Results Controller -@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; -@property (nonatomic, copy) NSString *resourcePath; -@property (nonatomic, retain) NSFetchRequest *fetchRequest; -@property (nonatomic, retain) NSPredicate *predicate; -@property (nonatomic, retain) NSArray *sortDescriptors; -@property (nonatomic, copy) NSString *sectionNameKeyPath; -@property (nonatomic, copy) NSString *cacheName; -@property (nonatomic, retain, readonly) NSFetchedResultsController *fetchedResultsController; - -// Configuring Headers and Sections -@property (nonatomic, assign) CGFloat heightForHeaderInSection; -@property (nonatomic, copy) RKFetchedResultsTableViewViewForHeaderInSectionBlock onViewForHeaderInSection; -@property (nonatomic, assign) BOOL showsSectionIndexTitles; - -// Sorting -@property (nonatomic, assign) SEL sortSelector; -@property (nonatomic, copy) NSComparator sortComparator; - -- (void)setObjectMappingForClass:(Class)objectClass; // TODO: Kill this API... mapping descriptors will cover use case. -- (void)loadTable; -- (void)loadTableFromNetwork; - -@end diff --git a/Code/UI/RKFetchedResultsTableController.m b/Code/UI/RKFetchedResultsTableController.m deleted file mode 100755 index 7f19526686..0000000000 --- a/Code/UI/RKFetchedResultsTableController.m +++ /dev/null @@ -1,709 +0,0 @@ -// -// RKFetchedResultsTableController.m -// RestKit -// -// Created by Blake Watters on 8/2/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 "RKFetchedResultsTableController.h" -#import "RKAbstractTableController_Internals.h" -#import "RKManagedObjectStore.h" -#import "RKMappingOperation.h" -#import "RKEntityMapping.h" -#import "RKLog.h" -#import "RKObjectMappingProvider+CoreData.h" - -// Define logging component -#undef RKLogComponent -#define RKLogComponent lcl_cRestKitUI - -@interface RKFetchedResultsTableController () - -@property (nonatomic, assign) BOOL isEmptyBeforeAnimation; -@property (nonatomic, retain, readwrite) NSFetchedResultsController *fetchedResultsController; -@property (nonatomic, retain) NSArray *arraySortedFetchedObjects; - -- (BOOL)performFetch:(NSError **)error; -- (void)updateSortedArray; -@end - -@implementation RKFetchedResultsTableController - -@dynamic delegate; -@synthesize fetchedResultsController = _fetchedResultsController; -@synthesize resourcePath = _resourcePath; -@synthesize heightForHeaderInSection = _heightForHeaderInSection; -@synthesize onViewForHeaderInSection = _onViewForHeaderInSection; -@synthesize predicate = _predicate; -@synthesize sortDescriptors = _sortDescriptors; -@synthesize sectionNameKeyPath = _sectionNameKeyPath; -@synthesize cacheName = _cacheName; -@synthesize showsSectionIndexTitles = _showsSectionIndexTitles; -@synthesize sortSelector = _sortSelector; -@synthesize sortComparator = _sortComparator; -@synthesize fetchRequest = _fetchRequest; -@synthesize arraySortedFetchedObjects = _arraySortedFetchedObjects; -@synthesize isEmptyBeforeAnimation = _isEmptyBeforeAnimation; - -- (void)dealloc -{ - _fetchedResultsController.delegate = nil; - [_fetchedResultsController release]; - _fetchedResultsController = nil; - [_resourcePath release]; - _resourcePath = nil; - [_predicate release]; - _predicate = nil; - [_sortDescriptors release]; - _sortDescriptors = nil; - [_sectionNameKeyPath release]; - _sectionNameKeyPath = nil; - [_cacheName release]; - _cacheName = nil; - [_arraySortedFetchedObjects release]; - _arraySortedFetchedObjects = nil; - [_fetchRequest release]; - _fetchRequest = nil; - Block_release(_onViewForHeaderInSection); - Block_release(_sortComparator); - [super dealloc]; -} - -#pragma mark - Helpers - -- (BOOL)performFetch:(NSError **)error -{ - NSAssert(self.fetchedResultsController, @"Cannot perform a fetch: self.fetchedResultsController is nil."); - - [NSFetchedResultsController deleteCacheWithName:self.fetchedResultsController.cacheName]; - BOOL success = [self.fetchedResultsController performFetch:error]; - if (!success) { - RKLogError(@"performFetch failed with error: %@", [*error localizedDescription]); - return NO; - } else { - RKLogTrace(@"performFetch completed successfully"); - for (NSUInteger index = 0; index < [self sectionCount]; index++) { - if ([self.delegate respondsToSelector:@selector(tableController:didInsertSectionAtIndex:)]) { - [self.delegate tableController:self didInsertSectionAtIndex:index]; - } - - if ([self.delegate respondsToSelector:@selector(tableController:didInsertObject:atIndexPath:)]) { - for (NSUInteger row = 0; row < [self numberOfRowsInSection:index]; row++) { - NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:index]; - id object = [self objectForRowAtIndexPath:indexPath]; - [self.delegate tableController:self didInsertObject:object atIndexPath:indexPath]; - } - } - } - } - - return YES; -} - -- (void)updateSortedArray -{ - self.arraySortedFetchedObjects = nil; - - if (self.sortSelector || self.sortComparator) { - if (self.sortSelector) { - self.arraySortedFetchedObjects = [self.fetchedResultsController.fetchedObjects sortedArrayUsingSelector:self.sortSelector]; - } else if (self.sortComparator) { - self.arraySortedFetchedObjects = [self.fetchedResultsController.fetchedObjects sortedArrayUsingComparator:self.sortComparator]; - } - - NSAssert(self.arraySortedFetchedObjects.count == self.fetchedResultsController.fetchedObjects.count, - @"sortSelector or sortComparator sort resulted in fewer objects than expected"); - } -} - -- (NSUInteger)headerSectionIndex -{ - return 0; -} - -- (BOOL)isHeaderSection:(NSUInteger)section -{ - return (section == [self headerSectionIndex]); -} - -- (BOOL)isHeaderRow:(NSUInteger)row -{ - BOOL isHeaderRow = NO; - NSUInteger headerItemCount = [self.headerItems count]; - if ([self isEmpty] && self.emptyItem) { - isHeaderRow = (row > 0 && row <= headerItemCount); - } else { - isHeaderRow = (row < headerItemCount); - } - return isHeaderRow; -} - -- (NSUInteger)footerSectionIndex -{ - return ([self sectionCount] - 1); -} - -- (BOOL)isFooterSection:(NSUInteger)section -{ - return (section == [self footerSectionIndex]); -} - -- (BOOL)isFooterRow:(NSUInteger)row -{ - NSUInteger sectionIndex = ([self sectionCount] - 1); - id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:sectionIndex]; - NSUInteger firstFooterIndex = [sectionInfo numberOfObjects]; - if (sectionIndex == 0) { - firstFooterIndex += (![self isEmpty] || self.showsHeaderRowsWhenEmpty) ? [self.headerItems count] : 0; - firstFooterIndex += ([self isEmpty] && self.emptyItem) ? 1 : 0; - } - - return row >= firstFooterIndex; -} - -- (BOOL)isHeaderIndexPath:(NSIndexPath *)indexPath -{ - return ((! [self isEmpty] || self.showsHeaderRowsWhenEmpty) && - [self.headerItems count] > 0 && - [self isHeaderSection:indexPath.section] && - [self isHeaderRow:indexPath.row]); -} - -- (BOOL)isFooterIndexPath:(NSIndexPath *)indexPath -{ - return ((! [self isEmpty] || self.showsFooterRowsWhenEmpty) && - [self.footerItems count] > 0 && - [self isFooterSection:indexPath.section] && - [self isFooterRow:indexPath.row]); -} - -- (BOOL)isEmptySection:(NSUInteger)section -{ - return (section == 0); -} - -- (BOOL)isEmptyRow:(NSUInteger)row -{ - return (row == 0); -} - -- (BOOL)isEmptyItemIndexPath:(NSIndexPath *)indexPath -{ - return ([self isEmpty] && self.emptyItem && - [self isEmptySection:indexPath.section] && - [self isEmptyRow:indexPath.row]); -} - -- (NSIndexPath *)emptyItemIndexPath -{ - return [NSIndexPath indexPathForRow:0 inSection:0]; -} - -- (NSIndexPath *)fetchedResultsIndexPathForIndexPath:(NSIndexPath *)indexPath -{ - if (([self isEmpty] && self.emptyItem && - [self isEmptySection:indexPath.section] && - ! [self isEmptyRow:indexPath.row]) || - ((! [self isEmpty] || self.showsHeaderRowsWhenEmpty) && - [self.headerItems count] > 0 && - [self isHeaderSection:indexPath.section] && - ! [self isHeaderRow:indexPath.row])) { - NSUInteger adjustedRowIndex = indexPath.row; - if (![self isEmpty] || self.showsHeaderRowsWhenEmpty) { - adjustedRowIndex -= [self.headerItems count]; - } - adjustedRowIndex -= ([self isEmpty] && self.emptyItem) ? 1 : 0; - return [NSIndexPath indexPathForRow:adjustedRowIndex - inSection:indexPath.section]; - } - return indexPath; -} - -- (NSIndexPath *)indexPathForFetchedResultsIndexPath:(NSIndexPath *)indexPath -{ - if (([self isEmpty] && self.emptyItem && - [self isEmptySection:indexPath.section] && - ! [self isEmptyRow:indexPath.row]) || - ((! [self isEmpty] || self.showsHeaderRowsWhenEmpty) && - [self.headerItems count] > 0 && - [self isHeaderSection:indexPath.section])) { - NSUInteger adjustedRowIndex = indexPath.row; - if (![self isEmpty] || self.showsHeaderRowsWhenEmpty) { - adjustedRowIndex += [self.headerItems count]; - } - adjustedRowIndex += ([self isEmpty] && self.emptyItem) ? 1 : 0; - return [NSIndexPath indexPathForRow:adjustedRowIndex - inSection:indexPath.section]; - } - return indexPath; -} - -#pragma mark - Public - -- (NSFetchRequest *)fetchRequest -{ - return _fetchRequest ? _fetchRequest : self.fetchedResultsController.fetchRequest; -} - -- (void)loadTable -{ - NSFetchRequest *fetchRequest = nil; - if (self.resourcePath) { - fetchRequest = [self.objectManager.mappingProvider fetchRequestForResourcePath:self.resourcePath]; - } else { - fetchRequest = self.fetchRequest; - } - NSAssert(fetchRequest != nil, @"Attempted to load RKFetchedResultsTableController with nil fetchRequest for resourcePath %@, fetchRequest %@", _resourcePath, _fetchRequest); - - if (self.predicate) { - [fetchRequest setPredicate:self.predicate]; - } - if (self.sortDescriptors) { - [fetchRequest setSortDescriptors:self.sortDescriptors]; - } - - RKLogTrace(@"Loading fetched results table view from managed object context %@ with fetch request: %@", self.managedObjectContext, fetchRequest); - NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest - managedObjectContext:self.managedObjectContext - sectionNameKeyPath:self.sectionNameKeyPath - cacheName:self.cacheName]; - self.fetchedResultsController = fetchedResultsController; - [fetchedResultsController release]; - self.fetchedResultsController.delegate = self; - - // Perform the load - NSError *error; - [self didStartLoad]; - BOOL success = [self performFetch:&error]; - if (! success) { - [self didFailLoadWithError:error]; - } - [self updateSortedArray]; - [self didFinishLoad]; - - // Load the table view after we have finished the load to ensure the state - // is accurate when computing the table view data source responses - [self.tableView reloadData]; - - if ([self isAutoRefreshNeeded] && [self isOnline] && - ![self.objectLoader isLoading] && - ![self.objectLoader.queue containsRequest:self.objectLoader]) { - [self performSelector:@selector(loadTableFromNetwork) withObject:nil afterDelay:0]; - } -} - -- (void)setSortSelector:(SEL)sortSelector -{ - NSAssert(self.sectionNameKeyPath == nil, @"Attempted to sort fetchedObjects across multiple sections"); - NSAssert(self.sortComparator == nil, @"Attempted to sort fetchedObjects with a sortSelector when a sortComparator already exists"); - self.sortSelector = sortSelector; -} - -- (void)setSortComparator:(NSComparator)sortComparator -{ - NSAssert(self.sectionNameKeyPath == nil, @"Attempted to sort fetchedObjects across multiple sections"); - NSAssert(self.sortSelector == nil, @"Attempted to sort fetchedObjects with a sortComparator when a sortSelector already exists"); - if (self.sortComparator) { - Block_release(self.sortComparator); - _sortComparator = nil; - } - _sortComparator = Block_copy(sortComparator); -} - -- (void)setSectionNameKeyPath:(NSString *)sectionNameKeyPath -{ - NSAssert(self.sortSelector == nil, @"Attempted to create a sectioned fetchedResultsController when a sortSelector is present"); - NSAssert(self.sortComparator == nil, @"Attempted to create a sectioned fetchedResultsController when a sortComparator is present"); - [sectionNameKeyPath retain]; - [_sectionNameKeyPath release]; - _sectionNameKeyPath = sectionNameKeyPath; -} - -- (void)setResourcePath:(NSString *)resourcePath -{ - [_resourcePath release]; - _resourcePath = [resourcePath copy]; - self.objectLoader = [self.objectManager loaderWithResourcePath:_resourcePath]; - self.objectLoader.delegate = self; -} - -- (void)setObjectMappingForClass:(Class)objectClass -{ - NSParameterAssert(objectClass != NULL); - NSAssert(self.objectLoader != NULL, @"Resource path (and thus object loader) must be set before setting object mapping."); - NSAssert(self.objectManager != NULL, @"Object manager must exist before setting object mapping."); - self.objectLoader.objectMapping = [self.objectManager.mappingProvider objectMappingForClass:objectClass]; -} - -#pragma mark - Managing Sections - -- (NSUInteger)sectionCount -{ - return [[self.fetchedResultsController sections] count]; -} - -- (NSUInteger)rowCount -{ - NSUInteger fetchedItemCount = [[self.fetchedResultsController fetchedObjects] count]; - NSUInteger nonFetchedItemCount = 0; - if (fetchedItemCount == 0) { - nonFetchedItemCount += self.emptyItem ? 1 : 0; - nonFetchedItemCount += self.showsHeaderRowsWhenEmpty ? [self.headerItems count] : 0; - nonFetchedItemCount += self.showsFooterRowsWhenEmpty ? [self.footerItems count] : 0; - } else { - nonFetchedItemCount += [self.headerItems count]; - nonFetchedItemCount += [self.footerItems count]; - } - return (fetchedItemCount + nonFetchedItemCount); -} - -- (NSIndexPath *)indexPathForObject:(id)object -{ - if ([object isKindOfClass:[NSManagedObject class]]) { - return [self indexPathForFetchedResultsIndexPath:[self.fetchedResultsController indexPathForObject:object]]; - } else if ([object isKindOfClass:[RKTableItem class]]) { - if ([object isEqual:self.emptyItem]) { - return ([self isEmpty]) ? [self emptyItemIndexPath] : nil; - } else if ([self.headerItems containsObject:object]) { - // Figure out the row number for the object - NSUInteger objectIndex = [self.headerItems indexOfObject:object]; - NSUInteger row = ([self isEmpty] && self.emptyItem) ? (objectIndex + 1) : objectIndex; - return [NSIndexPath indexPathForRow:row inSection:[self headerSectionIndex]]; - } else if ([self.footerItems containsObject:object]) { - NSUInteger footerSectionIndex = [self sectionCount] - 1; - id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:footerSectionIndex]; - NSUInteger numberOfFetchedResults = sectionInfo.numberOfObjects; - NSUInteger objectIndex = [self.footerItems indexOfObject:object]; - NSUInteger row = numberOfFetchedResults + objectIndex; - row += ([self isEmpty] && self.emptyItem) ? 1 : 0; - if ([self isHeaderSection:footerSectionIndex]) { - row += [self.headerItems count]; - } - - return [NSIndexPath indexPathForRow:row inSection:footerSectionIndex]; - } - } else { - RKLogWarning(@"Asked for indexPath of unsupported object type '%@': %@", [object class], object); - } - return nil; -} - -- (UITableViewCell *)cellForObject:(id)object -{ - NSIndexPath *indexPath = [self indexPathForObject:object]; - NSAssert(indexPath, @"Failed to find indexPath for object: %@", object); - return [self.tableView cellForRowAtIndexPath:indexPath]; -} - -#pragma mark - UITableViewDataSource methods - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView -{ - NSAssert(theTableView == self.tableView, @"numberOfSectionsInTableView: invoked with inappropriate tableView: %@", theTableView); - RKLogTrace(@"numberOfSectionsInTableView: %d (%@)", [[self.fetchedResultsController sections] count], [[self.fetchedResultsController sections] valueForKey:@"name"]); - return [[self.fetchedResultsController sections] count]; -} - -- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section -{ - NSAssert(theTableView == self.tableView, @"tableView:numberOfRowsInSection: invoked with inappropriate tableView: %@", theTableView); - RKLogTrace(@"%@ numberOfRowsInSection:%d = %d", self, section, self.sectionCount); - id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; - NSUInteger numberOfRows = [sectionInfo numberOfObjects]; - - if ([self isHeaderSection:section]) { - numberOfRows += (![self isEmpty] || self.showsHeaderRowsWhenEmpty) ? [self.headerItems count] : 0; - numberOfRows += ([self isEmpty] && self.emptyItem) ? 1 : 0; - } - - if ([self isFooterSection:section]) { - numberOfRows += (![self isEmpty] || self.showsFooterRowsWhenEmpty) ? [self.footerItems count] : 0; - } - return numberOfRows; -} - -- (NSString *)tableView:(UITableView *)theTableView titleForHeaderInSection:(NSInteger)section -{ - id sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section]; - return [sectionInfo name]; -} - -- (NSString *)tableView:(UITableView *)theTableView titleForFooterInSection:(NSInteger)section -{ - NSAssert(theTableView == self.tableView, @"tableView:titleForFooterInSection: invoked with inappropriate tableView: %@", theTableView); - return nil; -} - -- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)theTableView -{ - if (theTableView.style == UITableViewStylePlain && self.showsSectionIndexTitles) { - return [_fetchedResultsController sectionIndexTitles]; - } - return nil; -} - -- (NSInteger)tableView:(UITableView *)theTableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index -{ - if (theTableView.style == UITableViewStylePlain && self.showsSectionIndexTitles) { - return [self.fetchedResultsController sectionForSectionIndexTitle:title atIndex:index]; - } - return 0; -} - -- (void)tableView:(UITableView *)theTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSAssert(theTableView == self.tableView, @"tableView:commitEditingStyle:forRowAtIndexPath: invoked with inappropriate tableView: %@", theTableView); - if (self.canEditRows && editingStyle == UITableViewCellEditingStyleDelete) { - NSManagedObject *managedObject = [self objectForRowAtIndexPath:indexPath]; - RKObjectMapping *mapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[managedObject class]]; - if ([mapping isKindOfClass:[RKEntityMapping class]]) { - RKEntityMapping *managedObjectMapping = (RKEntityMapping *)mapping; - NSString *primaryKeyAttribute = managedObjectMapping.primaryKeyAttribute; - - if ([managedObject valueForKeyPath:primaryKeyAttribute]) { - RKLogTrace(@"About to fire a delete request for managedObject: %@", managedObject); - [[RKObjectManager sharedManager] deleteObject:managedObject delegate:self]; - } else { - RKLogTrace(@"About to locally delete managedObject: %@", managedObject); - NSManagedObjectContext *managedObjectContext = managedObject.managedObjectContext; - [managedObjectContext performBlock:^{ - [managedObjectContext deleteObject:managedObject]; - - NSError *error = nil; - [managedObjectContext save:&error]; - if (error) { - RKLogError(@"Failed to save managedObjectContext after a delete with error: %@", error); - } - }]; - } - } - } -} - -- (void)tableView:(UITableView *)theTableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destIndexPath -{ - NSAssert(theTableView == self.tableView, @"tableView:moveRowAtIndexPath:toIndexPath: invoked with inappropriate tableView: %@", theTableView); -} - -- (BOOL)tableView:(UITableView *)theTableView canEditRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSAssert(theTableView == self.tableView, @"tableView:canEditRowAtIndexPath: invoked with inappropriate tableView: %@", theTableView); - return self.canEditRows && [self isOnline] && !([self isHeaderIndexPath:indexPath] || [self isFooterIndexPath:indexPath] || [self isEmptyItemIndexPath:indexPath]); -} - -- (BOOL)tableView:(UITableView *)theTableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSAssert(theTableView == self.tableView, @"tableView:canMoveRowAtIndexPath: invoked with inappropriate tableView: %@", theTableView); - return self.canMoveRows && !([self isHeaderIndexPath:indexPath] || [self isFooterIndexPath:indexPath] || [self isEmptyItemIndexPath:indexPath]); -} - -#pragma mark - UITableViewDelegate methods - -- (CGFloat)tableView:(UITableView *)theTableView heightForHeaderInSection:(NSInteger)section -{ - NSAssert(theTableView == self.tableView, @"heightForHeaderInSection: invoked with inappropriate tableView: %@", theTableView); - return self.heightForHeaderInSection; -} - -- (CGFloat)tableView:(UITableView *)theTableView heightForFooterInSection:(NSInteger)sectionIndex -{ - NSAssert(theTableView == self.tableView, @"heightForFooterInSection: invoked with inappropriate tableView: %@", theTableView); - return 0; -} - -- (UIView *)tableView:(UITableView *)theTableView viewForHeaderInSection:(NSInteger)section -{ - NSAssert(theTableView == self.tableView, @"viewForHeaderInSection: invoked with inappropriate tableView: %@", theTableView); - if (self.onViewForHeaderInSection) { - NSString *sectionTitle = [self tableView:self.tableView titleForHeaderInSection:section]; - if (sectionTitle) { - return self.onViewForHeaderInSection(section, sectionTitle); - } - } - return nil; -} - -- (UIView *)tableView:(UITableView *)theTableView viewForFooterInSection:(NSInteger)sectionIndex -{ - NSAssert(theTableView == self.tableView, @"viewForFooterInSection: invoked with inappropriate tableView: %@", theTableView); - return nil; -} - -#pragma mark - Cell Mappings - -- (id)objectForRowAtIndexPath:(NSIndexPath *)indexPath -{ - if ([self isEmptyItemIndexPath:indexPath]) { - return self.emptyItem; - } else if ([self isHeaderIndexPath:indexPath]) { - NSUInteger row = ([self isEmpty] && self.emptyItem) ? (indexPath.row - 1) : indexPath.row; - return [self.headerItems objectAtIndex:row]; - } else if ([self isFooterIndexPath:indexPath]) { - id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:indexPath.section]; - NSUInteger footerRow = (indexPath.row - sectionInfo.numberOfObjects); - if (indexPath.section == 0) { - footerRow -= (![self isEmpty] || self.showsHeaderRowsWhenEmpty) ? [self.headerItems count] : 0; - footerRow -= ([self isEmpty] && self.emptyItem) ? 1 : 0; - } - return [self.footerItems objectAtIndex:footerRow]; - - } else if (self.sortSelector || self.sortComparator) { - return [self.arraySortedFetchedObjects objectAtIndex:[self fetchedResultsIndexPathForIndexPath:indexPath].row]; - } - - NSIndexPath *fetchedResultsIndexPath = [self fetchedResultsIndexPathForIndexPath:indexPath]; - id sectionInfo = [[_fetchedResultsController sections] objectAtIndex:fetchedResultsIndexPath.section]; - if (fetchedResultsIndexPath.row < [sectionInfo numberOfObjects]) { - return [self.fetchedResultsController objectAtIndexPath:fetchedResultsIndexPath]; - } else { - return nil; - } -} - -#pragma mark - Network Table Loading - -- (void)loadTableFromNetwork -{ - NSAssert(self.objectManager, @"Cannot perform a network load without an object manager"); - NSAssert(self.objectLoader, @"Cannot perform a network load when a network load is already in-progress"); - RKLogTrace(@"About to loadTableWithObjectLoader..."); - [self loadTableWithObjectLoader:self.objectLoader]; -} - -#pragma mark - KVO & Model States - -- (BOOL)isConsideredEmpty -{ - NSUInteger fetchedObjectsCount = [[_fetchedResultsController fetchedObjects] count]; - BOOL isEmpty = (fetchedObjectsCount == 0); - RKLogTrace(@"Determined isEmpty = %@. fetchedObjects count = %d", isEmpty ? @"YES" : @"NO", fetchedObjectsCount); - return isEmpty; -} - -#pragma mark - NSFetchedResultsControllerDelegate methods - -- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller -{ - RKLogTrace(@"Beginning updates for fetchedResultsController (%@). Current section count = %d (resource path: %@)", controller, [[controller sections] count], _resourcePath); - - if (self.sortSelector) return; - - [self.tableView beginUpdates]; - self.isEmptyBeforeAnimation = [self isEmpty]; -} - -- (void)controller:(NSFetchedResultsController *)controller - didChangeSection:(id)sectionInfo - atIndex:(NSUInteger)sectionIndex - forChangeType:(NSFetchedResultsChangeType)type -{ - - if (_sortSelector) return; - - switch (type) { - case NSFetchedResultsChangeInsert: - [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] - withRowAnimation:UITableViewRowAnimationFade]; - - if ([self.delegate respondsToSelector:@selector(tableController:didInsertSectionAtIndex:)]) { - [self.delegate tableController:self didInsertSectionAtIndex:sectionIndex]; - } - break; - - case NSFetchedResultsChangeDelete: - [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] - withRowAnimation:UITableViewRowAnimationFade]; - - if ([self.delegate respondsToSelector:@selector(tableController:didDeleteSectionAtIndex:)]) { - [self.delegate tableController:self didDeleteSectionAtIndex:sectionIndex]; - } - break; - - default: - RKLogTrace(@"Encountered unexpected section changeType: %d", type); - break; - } -} - -- (void)controller:(NSFetchedResultsController *)controller - didChangeObject:(id)anObject - atIndexPath:(NSIndexPath *)indexPath - forChangeType:(NSFetchedResultsChangeType)type - newIndexPath:(NSIndexPath *)newIndexPath -{ - - if (_sortSelector) return; - - NSIndexPath *adjIndexPath = [self indexPathForFetchedResultsIndexPath:indexPath]; - NSIndexPath *adjNewIndexPath = [self indexPathForFetchedResultsIndexPath:newIndexPath]; - - switch (type) { - case NSFetchedResultsChangeInsert: - [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:adjNewIndexPath] - withRowAnimation:UITableViewRowAnimationFade]; - break; - - case NSFetchedResultsChangeDelete: - [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:adjIndexPath] - withRowAnimation:UITableViewRowAnimationFade]; - break; - - case NSFetchedResultsChangeUpdate: - [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:adjIndexPath] - withRowAnimation:UITableViewRowAnimationFade]; - break; - - case NSFetchedResultsChangeMove: - [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:adjIndexPath] - withRowAnimation:UITableViewRowAnimationFade]; - [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:adjNewIndexPath] - withRowAnimation:UITableViewRowAnimationFade]; - break; - - default: - RKLogTrace(@"Encountered unexpected object changeType: %d", type); - break; - } -} - -- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller -{ - RKLogTrace(@"Ending updates for fetchedResultsController (%@). New section count = %d (resource path: %@)", - controller, [[controller sections] count], _resourcePath); - if (self.emptyItem && ![self isEmpty] && _isEmptyBeforeAnimation) { - [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[self emptyItemIndexPath]] - withRowAnimation:UITableViewRowAnimationFade]; - } - - [self updateSortedArray]; - - if (self.sortSelector) { - [self.tableView reloadData]; - } else { - [self.tableView endUpdates]; - } - - [self didFinishLoad]; -} - -#pragma mark - UITableViewDataSource methods - -- (NSUInteger)numberOfRowsInSection:(NSUInteger)index -{ - return [self tableView:self.tableView numberOfRowsInSection:index]; -} - -@end diff --git a/Code/UI/RKKeyboardScroller.h b/Code/UI/RKKeyboardScroller.h deleted file mode 100644 index 0a46dde4b5..0000000000 --- a/Code/UI/RKKeyboardScroller.h +++ /dev/null @@ -1,57 +0,0 @@ -// -// RKKeyboardScroller.h -// RestKit -// -// Created by Blake Watters on 7/5/12. -// Copyright (c) 2012 RestKit, Inc. 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. -// - -#if TARGET_OS_IPHONE -#import - -/** - RKKeyboardScroller objects provide support for the automatic adjustment of views - contained with a UIScrollView (or dervied classes, such as a UITableView) in response - to the appearance or disappearance of the keyboard. The scroller adjusts the content - inset of the scroll view being observed to accommodate the pixels consumed by the keyboard. - It also tracks the first responder and scrolls it into the visible field if obscured by - the appearance of the keyboard. - */ -@interface RKKeyboardScroller : NSObject - -/** - The view controller containing the target scroll view within its managed view hierarchy. - */ -@property (nonatomic, retain, readonly) UIViewController *viewController; - -/** - The scroll view that is to be scrolled in response to the appearance and disappearance of - the keyboard. - */ -@property (nonatomic, retain, readonly) UIScrollView *scrollView; - -/** - Instantiates the receiver with a view controller and scroll view that is to be scrolled - in response to keyboard notifications. - - @param viewController The view controller object that should have its view resized. - @param scrollView The scroll view that is to be scrolled in response to the keyboard - @return The receiver, initialized with the given view controller. - */ -- (id)initWithViewController:(UIViewController *)viewController scrollView:(UIScrollView *)scrollView; - -@end - -#endif diff --git a/Code/UI/RKKeyboardScroller.m b/Code/UI/RKKeyboardScroller.m deleted file mode 100644 index 2922fe82ca..0000000000 --- a/Code/UI/RKKeyboardScroller.m +++ /dev/null @@ -1,148 +0,0 @@ -// -// RKKeyboardScroller.m -// RestKit -// -// Created by Blake Watters on 7/5/12. -// Copyright (c) 2012 RestKit, Inc. 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 "RKKeyboardScroller.h" -#import "RKLog.h" -#import "UIView+FindFirstResponder.h" - -// Define logging component -#undef RKLogComponent -#define RKLogComponent lcl_cRestKitUI - -@interface RKKeyboardScroller () - -@property (nonatomic, retain, readwrite) UIViewController *viewController; -@property (nonatomic, retain, readwrite) UIScrollView *scrollView; -@end - -@implementation RKKeyboardScroller - -@synthesize viewController = _viewController; -@synthesize scrollView = _scrollView; - -- (id)init -{ - RKLogError(@"Failed to call designated initialized initWithViewController:"); - [self doesNotRecognizeSelector:_cmd]; - [self release]; - return nil; -} - -- (id)initWithViewController:(UIViewController *)viewController scrollView:(UIScrollView *)scrollView -{ - NSAssert(viewController, @"%@ must be instantiated with a viewController.", [self class]); - NSAssert(scrollView, @"%@ must be instantiated with a scrollView.", [self class]); - - self = [super init]; - if (self) { - self.viewController = viewController; - self.scrollView = scrollView; - - // Register for Keyboard notifications - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(handleKeyboardNotification:) - name:UIKeyboardWillShowNotification - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(handleKeyboardNotification:) - name:UIKeyboardWillHideNotification - object:nil]; - } - - return self; -} - -- (void)dealloc -{ - self.viewController = nil; - self.scrollView = nil; - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [super dealloc]; -} - -- (void)handleKeyboardNotification:(NSNotification *)notification -{ - NSDictionary *userInfo = [notification userInfo]; - - CGRect keyboardEndFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; - CGFloat heightForViewShift = keyboardEndFrame.size.height; - RKLogTrace(@"keyboardEndFrame.size.height=%f, heightForViewShift=%f", - keyboardEndFrame.size.height, heightForViewShift); - - CGFloat bottomBarOffset = 0.0; - UINavigationController *navigationController = self.viewController.navigationController; - if (navigationController && navigationController.toolbar && !navigationController.toolbarHidden) { - bottomBarOffset += navigationController.toolbar.frame.size.height; - RKLogTrace(@"Found a visible toolbar. Reducing size of heightForViewShift by=%f", bottomBarOffset); - } - - UITabBarController *tabBarController = self.viewController.tabBarController; - if (tabBarController && tabBarController.tabBar && !self.viewController.hidesBottomBarWhenPushed) { - bottomBarOffset += tabBarController.tabBar.frame.size.height; - RKLogTrace(@"Found a visible tabBar. Reducing size of heightForViewShift by=%f", bottomBarOffset); - } - - if ([[notification name] isEqualToString:UIKeyboardWillShowNotification]) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.2]; - - UIEdgeInsets contentInsets = UIEdgeInsetsMake(0, 0, (heightForViewShift - bottomBarOffset), 0); - self.scrollView.contentInset = contentInsets; - self.scrollView.scrollIndicatorInsets = contentInsets; - - CGRect nonKeyboardRect = self.scrollView.frame; - nonKeyboardRect.size.height -= heightForViewShift; - RKLogTrace(@"Searching for a firstResponder not inside our nonKeyboardRect (%f, %f, %f, %f)", - nonKeyboardRect.origin.x, nonKeyboardRect.origin.y, - nonKeyboardRect.size.width, nonKeyboardRect.size.height); - - UIView *firstResponder = [self.scrollView findFirstResponder]; - if (firstResponder) { - CGRect firstResponderFrame = firstResponder.frame; - RKLogTrace(@"Found firstResponder=%@ at (%f, %f, %f, %f)", firstResponder, - firstResponderFrame.origin.x, firstResponderFrame.origin.y, - firstResponderFrame.size.width, firstResponderFrame.size.width); - - if (![firstResponder.superview isEqual:self.scrollView]) { - firstResponderFrame = [firstResponder.superview convertRect:firstResponderFrame toView:self.scrollView]; - RKLogTrace(@"firstResponder (%@) frame is not in viewToBeResized's coordinate system. Coverted to (%f, %f, %f, %f)", - firstResponder, firstResponderFrame.origin.x, firstResponderFrame.origin.y, - firstResponderFrame.size.width, firstResponderFrame.size.height); - } - - if (!CGRectContainsPoint(nonKeyboardRect, firstResponderFrame.origin)) { - RKLogTrace(@"firstResponder (%@) is underneath keyboard. Beginning scroll of tableView to show", firstResponder); - [self.scrollView scrollRectToVisible:firstResponderFrame animated:YES]; - } - } - [UIView commitAnimations]; - - } else if ([[notification name] isEqualToString:UIKeyboardWillHideNotification]) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.2]; - UIEdgeInsets contentInsets = UIEdgeInsetsZero; - self.scrollView.contentInset = contentInsets; - self.scrollView.scrollIndicatorInsets = contentInsets; - [UIView commitAnimations]; - } -} - -@end diff --git a/Code/UI/RKObjectManager+RKTableController.h b/Code/UI/RKObjectManager+RKTableController.h deleted file mode 100644 index c6d8ff43d9..0000000000 --- a/Code/UI/RKObjectManager+RKTableController.h +++ /dev/null @@ -1,60 +0,0 @@ -// -// RKObjectManager+RKTableController.h -// RestKit -// -// Created by Blake Watters on 2/23/12. -// Copyright (c) 2009-2012 RestKit. All rights reserved. -// - -#import "RKObjectManager.h" - -#if TARGET_OS_IPHONE - -@class RKTableController, RKFetchedResultsTableController; - -/** - Provides extensions to RKObjectManager for instantiating RKTableController instances - */ -@interface RKObjectManager (RKTableController) - -/** - Creates and returns a table controller object capable of loading remote object representations - into a UITableView using the RestKit object mapping engine for a given table view controller. - - @param tableViewController A UITableViewController to instantiate a table controller for - @return An RKTableController instance ready to drive the table view for the provided tableViewController. - */ -- (RKTableController *)tableControllerForTableViewController:(UITableViewController *)tableViewController; - -/** - Creates and returns a table controller object capable of loading remote object representations - into a UITableView using the RestKit object mapping engine for a given table view and view controller. - - @param tableView The UITableView object that table controller with acts as the delegate and data source for. - @param viewController The UIViewController that owns the specified tableView. - @return An RKTableController instance ready to drive the table view for the provided tableViewController. - */ -- (RKTableController *)tableControllerWithTableView:(UITableView *)tableView forViewController:(UIViewController *)viewController; - -/** - Creates and returns a fetched results table controller object capable of loading remote object representations - stored in Core Data into a UITableView using the RestKit object mapping engine for a given table view controller. - - @param tableViewController A UITableViewController to instantiate a table controller for - @return An RKFetchedResultsTableController instance ready to drive the table view for the provided tableViewController. - */ -- (RKFetchedResultsTableController *)fetchedResultsTableControllerForTableViewController:(UITableViewController *)tableViewController; - -/** - Creates and returns a table controller object capable of loading remote object representations - stored in Core Data into a UITableView using the RestKit object mapping engine for a given table view and view controller. - - @param tableView The UITableView object that table controller with acts as the delegate and data source for. - @param viewController The UIViewController that owns the specified tableView. - @return An RKFetchedResultsTableController instance ready to drive the table view for the provided tableViewController. - */ -- (RKFetchedResultsTableController *)fetchedResultsTableControllerWithTableView:(UITableView *)tableView forViewController:(UIViewController *)viewController; - -@end - -#endif diff --git a/Code/UI/RKObjectManager+RKTableController.m b/Code/UI/RKObjectManager+RKTableController.m deleted file mode 100644 index f76eb3a706..0000000000 --- a/Code/UI/RKObjectManager+RKTableController.m +++ /dev/null @@ -1,50 +0,0 @@ -// -// RKObjectManager+RKTableController.m -// RestKit -// -// Created by Blake Watters on 2/23/12. -// Copyright (c) 2009-2012 RestKit. All rights reserved. -// - -#import "RKObjectManager+RKTableController.h" - -#if TARGET_OS_IPHONE - -#import "RKTableController.h" -#import "RKFetchedResultsTableController.h" - -@implementation RKObjectManager (RKTableController) - -- (RKTableController *)tableControllerForTableViewController:(UITableViewController *)tableViewController -{ - RKTableController *tableController = [RKTableController tableControllerForTableViewController:tableViewController]; - tableController.objectManager = self; - return tableController; -} - -- (RKTableController *)tableControllerWithTableView:(UITableView *)tableView forViewController:(UIViewController *)viewController -{ - RKTableController *tableController = [RKTableController tableControllerWithTableView:tableView forViewController:viewController]; - tableController.objectManager = self; - return tableController; -} - -- (RKFetchedResultsTableController *)fetchedResultsTableControllerForTableViewController:(UITableViewController *)tableViewController -{ - RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerForTableViewController:tableViewController]; - tableController.objectManager = self; - tableController.managedObjectContext = self.managedObjectStore.mainQueueManagedObjectContext; - return tableController; -} - -- (RKFetchedResultsTableController *)fetchedResultsTableControllerWithTableView:(UITableView *)tableView forViewController:(UIViewController *)viewController -{ - RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerWithTableView:tableView forViewController:viewController]; - tableController.objectManager = self; - tableController.managedObjectContext = self.managedObjectStore.mainQueueManagedObjectContext; - return tableController; -} - -@end - -#endif diff --git a/Code/UI/RKRefreshGestureRecognizer.h b/Code/UI/RKRefreshGestureRecognizer.h deleted file mode 100644 index 0e958bd2cf..0000000000 --- a/Code/UI/RKRefreshGestureRecognizer.h +++ /dev/null @@ -1,43 +0,0 @@ -// RKRefreshGestureRecognizer.h -// RestKit -// -// Based on PHRefreshTriggerView by Pier-Olivier Thibault -// Adapted by Gregory S. Combs on 1/13/2012 -// -// 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. -// - -#if TARGET_OS_IPHONE - -#import -#import "RKRefreshTriggerView.h" - -typedef enum { - RKRefreshIdle = 0, - RKRefreshTriggered, - RKRefreshLoading -} RKRefreshState; - -@protocol RKRefreshTriggerProtocol -@optional -- (NSDate *)pullToRefreshDataSourceLastUpdated:(UIGestureRecognizer *)recognizer; -- (BOOL)pullToRefreshDataSourceIsLoading:(UIGestureRecognizer *)recognizer; -@end - -@interface RKRefreshGestureRecognizer : UIGestureRecognizer -@property (nonatomic, assign) RKRefreshState refreshState; // You can force a gesture state by modifying this value. -@property (nonatomic, readonly) UIScrollView *scrollView; -@property (nonatomic, readonly, retain) RKRefreshTriggerView *triggerView; -@end - -#endif diff --git a/Code/UI/RKRefreshGestureRecognizer.m b/Code/UI/RKRefreshGestureRecognizer.m deleted file mode 100644 index 0917f2992f..0000000000 --- a/Code/UI/RKRefreshGestureRecognizer.m +++ /dev/null @@ -1,243 +0,0 @@ -// RKRefreshGestureRecognizer.m -// RestKit -// -// Based on PHRefreshTriggerView by Pier-Olivier Thibault -// Adapted by Gregory S. Combs on 1/13/2012 -// -// 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. -// - -#if TARGET_OS_IPHONE - -#import -#import -#import "RKRefreshGestureRecognizer.h" - -NSString * const RKRefreshGestureAnimationKey = @"RKRefreshGestureAnimationKey"; -NSString * const RKRefreshResetGestureAnimationKey = @"RKRefreshResetGestureAnimationKey"; -static CGFloat const kFlipArrowAnimationTime = 0.18f; -static CGFloat const kDefaultTriggerViewHeight = 64.f; - -@interface RKRefreshGestureRecognizer () - -- (CABasicAnimation *)triggeredAnimation; -- (CABasicAnimation *)idlingAnimation; - -@property (nonatomic, retain, readwrite) RKRefreshTriggerView *triggerView; -@property (nonatomic, assign) BOOL isBoundToScrollView; -@property (nonatomic, retain) NSDateFormatter *dateFormatter; - -@end - -@implementation RKRefreshGestureRecognizer -#pragma mark - Synthesizers -@synthesize triggerView = _triggerView; -@synthesize refreshState = _refreshState; -@synthesize isBoundToScrollView = _isBoundToScrollView; -@synthesize dateFormatter = _dateFormatter; - -#pragma mark - Life Cycle -- (id)initWithTarget:(id)target action:(SEL)action -{ - - self = [super initWithTarget:target action:action]; - if (self) { - _triggerView = [[RKRefreshTriggerView alloc] initWithFrame:CGRectZero]; - _triggerView.titleLabel.text = NSLocalizedString(@"Pull down to refresh...", @"Pull down to refresh status"); - _dateFormatter = [[NSDateFormatter alloc] init]; - [_dateFormatter setDateStyle:NSDateFormatterShortStyle]; - [_dateFormatter setTimeStyle:NSDateFormatterShortStyle]; - [self addObserver:self forKeyPath:@"view" options:NSKeyValueObservingOptionNew context:nil]; - } - return self; -} - -- (void)dealloc -{ - [self removeObserver:self forKeyPath:@"view"]; - if (self.triggerView) - [self.triggerView removeFromSuperview]; - self.triggerView = nil; - [super dealloc]; -} - -#pragma mark - Utilities - -- (void)refreshLastUpdatedDate -{ - - SEL lastUpdatedSelector = @selector(pullToRefreshDataSourceLastUpdated:); - if (self.scrollView.delegate && [self.scrollView.delegate respondsToSelector:lastUpdatedSelector]) { - NSDate *date = [self.scrollView.delegate performSelector:lastUpdatedSelector withObject:self]; - if (!date) - return; - NSString *lastUpdatedText = [NSString stringWithFormat:@"Last Updated: %@", [self.dateFormatter stringFromDate:date]]; - self.triggerView.lastUpdatedLabel.text = lastUpdatedText; - - } else { - self.triggerView.lastUpdatedLabel.text = nil; - } - -} - -- (void)setRefreshState:(RKRefreshState)refreshState -{ - if (refreshState == _refreshState) - return; - - __block UIScrollView *bScrollView = self.scrollView; - - switch (refreshState) { - - case RKRefreshTriggered: { - if (![self.triggerView.arrowView.layer animationForKey:RKRefreshGestureAnimationKey]) - [self.triggerView.arrowView.layer addAnimation:[self triggeredAnimation] forKey:RKRefreshGestureAnimationKey]; - self.triggerView.titleLabel.text = NSLocalizedString(@"Release to refresh...", @"Release to refresh status"); - } - break; - - case RKRefreshIdle: { - if (_refreshState == RKRefreshLoading) { - [UIView animateWithDuration:0.2 animations:^{ - bScrollView.contentInset = UIEdgeInsetsMake(0, - bScrollView.contentInset.left, - bScrollView.contentInset.bottom, - bScrollView.contentInset.right); - }]; - - [self.triggerView.arrowView.layer removeAllAnimations]; - [self.triggerView.activityView removeFromSuperview]; - [self.triggerView.activityView stopAnimating]; - [self.triggerView addSubview:self.triggerView.arrowView]; - - } else if (_refreshState == RKRefreshTriggered) { - if ([self.triggerView.arrowView.layer animationForKey:RKRefreshGestureAnimationKey]) { - [self.triggerView.arrowView.layer addAnimation:[self idlingAnimation] forKey:RKRefreshResetGestureAnimationKey]; - } - } - [self refreshLastUpdatedDate]; - self.triggerView.titleLabel.text = NSLocalizedString(@"Pull down to refresh...", @"Pull down to refresh status"); - } - break; - - case RKRefreshLoading: { - [UIView animateWithDuration:0.2 animations:^{ - bScrollView.contentInset = UIEdgeInsetsMake(kDefaultTriggerViewHeight, - bScrollView.contentInset.left, - bScrollView.contentInset.bottom, - bScrollView.contentInset.right); - }]; - self.triggerView.titleLabel.text = NSLocalizedString(@"Loading...", @"Loading Status"); - [self.triggerView.arrowView removeFromSuperview]; - [self.triggerView addSubview:self.triggerView.activityView]; - [self.triggerView.activityView startAnimating]; - } - break; - } - - _refreshState = refreshState; -} - -- (CABasicAnimation *)triggeredAnimation -{ - CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; - animation.duration = kFlipArrowAnimationTime; - animation.toValue = [NSNumber numberWithDouble:M_PI]; - animation.fillMode = kCAFillModeForwards; - animation.removedOnCompletion = NO; - return animation; -} - -- (CABasicAnimation *)idlingAnimation -{ - CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; - animation.delegate = self; - animation.duration = kFlipArrowAnimationTime; - animation.toValue = [NSNumber numberWithDouble:0]; - animation.removedOnCompletion = YES; - return animation; -} - -- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag -{ - [self.triggerView.arrowView.layer removeAllAnimations]; -} - -- (UIScrollView *)scrollView -{ - return (UIScrollView *)self.view; -} - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ - id obj = [object valueForKeyPath:keyPath]; - if (NO == [obj isKindOfClass:[UIScrollView class]]) { - self.isBoundToScrollView = NO; - return; - } - self.isBoundToScrollView = YES; - self.triggerView.frame = CGRectMake(0, -kDefaultTriggerViewHeight, CGRectGetWidth(self.view.frame), kDefaultTriggerViewHeight); - [obj addSubview:self.triggerView]; -} - -#pragma mark UIGestureRecognizer -- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer -{ - return NO; -} - -- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer -{ - return NO; -} - -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event -{ - if (!self.isBoundToScrollView) - return; - if (self.state < UIGestureRecognizerStateBegan) { - self.state = UIGestureRecognizerStateBegan; - } - - if (self.scrollView.contentOffset.y < -kDefaultTriggerViewHeight) { - self.refreshState = RKRefreshTriggered; - self.state = UIGestureRecognizerStateChanged; - } else if (self.state != UIGestureRecognizerStateRecognized) { - self.refreshState = RKRefreshIdle; - self.state = UIGestureRecognizerStateChanged; - } -} - -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event -{ - if (!self.isBoundToScrollView) { - self.state = UIGestureRecognizerStateFailed; - return; - } - if (self.refreshState == RKRefreshTriggered) { - self.refreshState = RKRefreshLoading; - self.state = UIGestureRecognizerStateRecognized; - return; - } - self.state = UIGestureRecognizerStateCancelled; - self.refreshState = RKRefreshIdle; -} - -- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event -{ - self.state = UIGestureRecognizerStateCancelled; -} - -@end - -#endif diff --git a/Code/UI/RKRefreshTriggerView.h b/Code/UI/RKRefreshTriggerView.h deleted file mode 100644 index fc0853cf0b..0000000000 --- a/Code/UI/RKRefreshTriggerView.h +++ /dev/null @@ -1,42 +0,0 @@ -// RKRefreshTriggerView.h -// RestKit -// -// Based on PHRefreshTriggerView by Pier-Olivier Thibault -// Adapted by Gregory S. Combs on 1/13/2012 -// -// 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. -// - -#if TARGET_OS_IPHONE - -#import - -@interface RKRefreshTriggerView : UIView -@property (nonatomic, retain) UILabel *titleLabel; -@property (nonatomic, retain) UILabel *lastUpdatedLabel; -@property (nonatomic, retain) UIImageView *arrowView; -@property (nonatomic, retain) UIActivityIndicatorView *activityView; - -#ifdef UI_APPEARANCE_SELECTOR -@property (nonatomic, assign) UIImage *arrowImage UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) UIActivityIndicatorViewStyle activityIndicatorStyle UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) UIFont *titleFont UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) UIColor *titleColor UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) UIFont *lastUpdatedFont UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) UIColor *lastUpdatedColor UI_APPEARANCE_SELECTOR; -@property (nonatomic, retain) UIColor *refreshBackgroundColor UI_APPEARANCE_SELECTOR; -#endif - -@end - -#endif diff --git a/Code/UI/RKRefreshTriggerView.m b/Code/UI/RKRefreshTriggerView.m deleted file mode 100644 index 0bb10e52e1..0000000000 --- a/Code/UI/RKRefreshTriggerView.m +++ /dev/null @@ -1,196 +0,0 @@ -// RKRefreshTriggerView.h -// RestKit -// -// Based on PHRefreshTriggerView by Pier-Olivier Thibault -// Adapted by Gregory S. Combs on 1/13/2012 -// -// 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. -// -// TODO: Figure out how to automatically install RestKitResources.bundle and use that bundle path for arrow images - -#import "RKRefreshTriggerView.h" - -#if TARGET_OS_IPHONE - -#define DEFAULT_REFRESH_TITLE_FONT [UIFont boldSystemFontOfSize:13.0f] -#define DEFAULT_REFRESH_TITLE_COLOR [UIColor darkGrayColor] -#define DEFAULT_REFRESH_UPDATED_FONT [UIFont systemFontOfSize:12.0f] -#define DEFAULT_REFRESH_UPDATED_COLOR [UIColor lightGrayColor] -#define DEFAULT_REFRESH_ARROW_IMAGE [UIImage imageNamed:@"blueArrow"] -#define DEFAULT_REFRESH_ACTIVITY_STYLE UIActivityIndicatorViewStyleWhite - -@interface RKRefreshTriggerView () -@end - -@implementation RKRefreshTriggerView -@synthesize titleLabel = _titleLabel; -@synthesize activityView = _activityView; -@synthesize arrowView = _arrowView; -@synthesize lastUpdatedLabel = _lastUpdatedLabel; - -- (id)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - if (self) { - self.autoresizingMask = UIViewAutoresizingFlexibleWidth; - self.backgroundColor = [UIColor clearColor]; - - _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; - _titleLabel.textAlignment = UITextAlignmentCenter; - _titleLabel.backgroundColor = [UIColor clearColor]; - _titleLabel.font = DEFAULT_REFRESH_TITLE_FONT; - _titleLabel.textColor = DEFAULT_REFRESH_TITLE_COLOR; - [self addSubview:_titleLabel]; - - _lastUpdatedLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _lastUpdatedLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; - _lastUpdatedLabel.backgroundColor = [UIColor clearColor]; - _lastUpdatedLabel.textAlignment = UITextAlignmentCenter; - _lastUpdatedLabel.font = DEFAULT_REFRESH_UPDATED_FONT; - _lastUpdatedLabel.textColor = DEFAULT_REFRESH_UPDATED_COLOR; - [self addSubview:_lastUpdatedLabel]; - - _arrowView = [[UIImageView alloc] initWithImage:DEFAULT_REFRESH_ARROW_IMAGE]; - _arrowView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin; - [self addSubview:_arrowView]; - - _activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:DEFAULT_REFRESH_ACTIVITY_STYLE]; - _activityView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin; - } - return self; -} - - -- (void)dealloc -{ - self.titleLabel = nil; - self.arrowView = nil; - self.activityView = nil; - self.lastUpdatedLabel = nil; - [super dealloc]; -} - - -- (void)layoutSubviews -{ - CGPoint imageCenter = CGPointMake(30, CGRectGetMidY(self.bounds)); - self.arrowView.center = imageCenter; - self.arrowView.frame = CGRectIntegral(self.arrowView.frame); - self.activityView.center = imageCenter; - self.titleLabel.frame = CGRectIntegral(CGRectMake(0.0f, (CGRectGetHeight(self.bounds) * .25f), CGRectGetWidth(self.bounds), 20.0f)); - self.lastUpdatedLabel.frame = CGRectOffset(self.titleLabel.frame, 0.f, 18.f); -} - -#ifdef UI_APPEARANCE_SELECTOR - -#pragma mark - Proxy Accessors for UIAppearance - -- (UIImage *)arrowImage -{ - if (!self.arrowView) - return DEFAULT_REFRESH_ARROW_IMAGE; - return _arrowView.image; -} - -- (void)setArrowImage:(UIImage *)image -{ - if (!self.arrowView) - return; - self.arrowView.image = image; -} - -- (UIActivityIndicatorViewStyle)activityIndicatorStyle -{ - if (!self.activityView) - return DEFAULT_REFRESH_ACTIVITY_STYLE; - return self.activityView.activityIndicatorViewStyle; -} - -- (void)setActivityIndicatorStyle:(UIActivityIndicatorViewStyle)style -{ - if (!self.activityView) - return; - self.activityView.activityIndicatorViewStyle = style; -} - -- (UIFont *)titleFont -{ - if (!self.titleLabel) - return DEFAULT_REFRESH_TITLE_FONT; - return self.titleLabel.font; -} - -- (void)setTitleFont:(UIFont *)font -{ - if (!self.titleLabel) - return; - self.titleLabel.font = font; -} - -- (UIColor *)titleColor -{ - if (!self.titleLabel) - return DEFAULT_REFRESH_TITLE_COLOR; - return self.titleLabel.textColor; -} - -- (void)setTitleColor:(UIColor *)color -{ - if (!self.titleLabel) - return; - self.titleLabel.textColor = color; -} - -- (UIFont *)lastUpdatedFont -{ - if (!self.lastUpdatedLabel) - return DEFAULT_REFRESH_UPDATED_FONT; - return self.lastUpdatedLabel.font; -} - -- (void)setLastUpdatedFont:(UIFont *)font -{ - if (!self.lastUpdatedLabel) - return; - self.lastUpdatedLabel.font = font; -} - -- (UIColor *)lastUpdatedColor -{ - if (!self.lastUpdatedLabel) - return DEFAULT_REFRESH_UPDATED_COLOR; - return self.lastUpdatedLabel.textColor; -} - -- (void)setLastUpdatedColor:(UIColor *)color -{ - if (!self.lastUpdatedLabel) - return; - self.lastUpdatedLabel.textColor = color; -} - -- (UIColor *)refreshBackgroundColor -{ - return self.backgroundColor; -} - -- (void)setRefreshBackgroundColor:(UIColor *)backgroundColor -{ - [self setBackgroundColor:backgroundColor]; -} -#endif - -@end - -#endif diff --git a/Code/UI/RKTableCellBlockTypes.h b/Code/UI/RKTableCellBlockTypes.h deleted file mode 100644 index 6aabb9e8fd..0000000000 --- a/Code/UI/RKTableCellBlockTypes.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// RKTableCellBlockTypes.h -// RestKit -// -// Created by Blake Watters on 6/6/12. -// Copyright (c) 2012 RestKit. All rights reserved. -// - -typedef NSIndexPath *(^RKTableTargetIndexPathForMoveBlock)(UITableViewCell *cell, id object, NSIndexPath *sourceIndexPath, NSIndexPath *destIndexPath); -typedef UITableViewCellEditingStyle(^RKTableCellEditingStyleForObjectAtIndexPathBlock)(UITableViewCell *cell, id object, NSIndexPath *indexPath); -typedef NSString *(^RKTableStringForObjectAtIndexPathBlock)(UITableViewCell *cell, id object, NSIndexPath *indexPath); -typedef CGFloat(^RKTableHeightOfCellForObjectAtIndexPathBlock)(id object, NSIndexPath *indexPath); -typedef void(^RKTableVoidBlock)(); -typedef void(^RKTableCellBlock)(UITableViewCell *cell); -typedef void(^RKTableCellForObjectAtIndexPathBlock)(UITableViewCell *cell, id object, NSIndexPath *indexPath); diff --git a/Code/UI/RKTableController.h b/Code/UI/RKTableController.h deleted file mode 100644 index f4ce545e85..0000000000 --- a/Code/UI/RKTableController.h +++ /dev/null @@ -1,155 +0,0 @@ -// -// RKTableController.h -// RestKit -// -// Created by Blake Watters on 8/1/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. -// - -#if TARGET_OS_IPHONE -#import -#import "RKAbstractTableController.h" -#import "RKTableSection.h" -#import "RKTableViewCellMappings.h" -#import "RKTableItem.h" -#import "RKObjectManager.h" -#import "RKObjectMapping.h" -#import "RKObjectLoader.h" - -@protocol RKTableControllerDelegate - -@optional - -- (void)tableController:(RKTableController *)tableController didLoadObjects:(NSArray *)objects inSection:(RKTableSection *)section; - -@end - -@interface RKTableController : RKAbstractTableController - -@property (nonatomic, assign) id delegate; - -///----------------------------------------------------------------------------- -/// @name Static Tables -///----------------------------------------------------------------------------- - -- (void)loadObjects:(NSArray *)objects; -- (void)loadObjects:(NSArray *)objects inSection:(NSUInteger)sectionIndex; -- (void)loadEmpty; - -/** - Load an array of RKTableItems into table cells of the specified class. A table cell - mapping will be constructed on your behalf and yielded to the block for configuration. - After the block is invoked, the objects will be loaded into the specified section. - */ -// TODO: Update comments... -- (void)loadTableItems:(NSArray *)tableItems withMapping:(RKTableViewCellMapping *)cellMapping; -- (void)loadTableItems:(NSArray *)tableItems - inSection:(NSUInteger)sectionIndex - withMapping:(RKTableViewCellMapping *)cellMapping; - -/** - Load an array of RKTableItem objects into the table using the default - RKTableViewCellMapping. An instance of the cell mapping will be created on your - behalf and configured with the default table view cell attribute mappings. - - @param tableItems An array of RKTableItem instances to load into the table - - @see RKTableItem - @see [RKTableViewCellMapping addDefaultMappings] - */ -- (void)loadTableItems:(NSArray *)tableItems; - -/** - Load an array of RKTableItem objects into the specified section with the table using the default - RKTableViewCellMapping. An instance of the cell mapping will be created on your - behalf and configured with the default table view cell attribute mappings. - - @param tableItems An array of RKTableItem instances to load into the table - @param sectionIndex The section to load the table items into. Must be less than sectionCount. - - @see RKTableItem - @see [RKTableViewCellMapping addDefaultMappings] - */ -- (void)loadTableItems:(NSArray *)tableItems inSection:(NSUInteger)sectionIndex; - -///----------------------------------------------------------------------------- -/** @name Network Tables */ -///----------------------------------------------------------------------------- - -- (void)loadTableFromResourcePath:(NSString *)resourcePath; -- (void)loadTableFromResourcePath:(NSString *)resourcePath usingBlock:(void (^)(RKObjectLoader *objectLoader))block; - -///----------------------------------------------------------------------------- -/// @name Managing Sections -///----------------------------------------------------------------------------- - -@property (nonatomic, readonly) NSMutableArray *sections; - -/** - The key path on the loaded objects used to determine the section they belong to. - */ -@property (nonatomic, copy) NSString *sectionNameKeyPath; - -/** - Returns the section at the specified index. - @param index Must be less than the total number of sections. - */ -- (RKTableSection *)sectionAtIndex:(NSUInteger)index; - -/** - Returns the first section with the specified header title. - @param title The header title. - */ -- (RKTableSection *)sectionWithHeaderTitle:(NSString *)title; - -/** - Returns the index of the specified section. - - @param section Must be a valid non nil RKTableViewSection. - @return The index of the given section if contained within the receiver, otherwise NSNotFound. - */ -- (NSUInteger)indexForSection:(RKTableSection *)section; - -// Coalesces a series of table view updates performed within the block into -// a single animation using beginUpdates: and endUpdates: on the table view -// TODO: Move to super-class? -- (void)updateTableViewUsingBlock:(void (^)())block; - -/** Adds a new section to the model. - * @param section Must be a valid non nil RKTableViewSection. */ -// NOTE: connects cellMappings if section.cellMappings is nil... -- (void)addSection:(RKTableSection *)section; - -/** Inserts a new section at the specified index. - * @param section Must be a valid non nil RKTableViewSection. - * @param index Must be less than the total number of sections. */ -- (void)insertSection:(RKTableSection *)section atIndex:(NSUInteger)index; - -/** Removes the specified section from the model. - * @param section The section to remove. */ -- (void)removeSection:(RKTableSection *)section; - -/** Removes the section at the specified index from the model. - * @param index Must be less than the total number of section. */ -- (void)removeSectionAtIndex:(NSUInteger)index; - -/** Removes all sections from the model. */ -// NOTE: Adds a new section 0 -- (void)removeAllSections; -- (void)removeAllSections:(BOOL)recreateFirstSection; - -@end - -#endif // TARGET_OS_IPHONE diff --git a/Code/UI/RKTableController.m b/Code/UI/RKTableController.m deleted file mode 100644 index b818450c81..0000000000 --- a/Code/UI/RKTableController.m +++ /dev/null @@ -1,520 +0,0 @@ -// -// RKTableController.m -// RestKit -// -// Created by Blake Watters on 8/1/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 "RKTableController.h" -#import "RKAbstractTableController_Internals.h" -#import "RKLog.h" -#import "NSArray+RKAdditions.h" -#import "RKMappingOperation.h" -#import "RKMappingOperationDataSource.h" - -// Define logging component -#undef RKLogComponent -#define RKLogComponent lcl_cRestKitUI - -@interface RKTableController () -@property (nonatomic, readwrite) NSMutableArray *sections; -@end - -@implementation RKTableController - -@dynamic delegate; -@synthesize sectionNameKeyPath = _sectionNameKeyPath; -@synthesize sections = _sections; - -#pragma mark - Instantiation - -- (id)init -{ - self = [super init]; - if (self) { - _sections = [NSMutableArray new]; - [self addObserver:self - forKeyPath:@"sections" - options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld - context:nil]; - - RKTableSection *section = [RKTableSection section]; - [self addSection:section]; - } - - return self; -} - -- (void)dealloc -{ - [self removeObserver:self forKeyPath:@"sections"]; - [_sectionNameKeyPath release]; - [_sections release]; - - [super dealloc]; -} - -#pragma mark - Managing Sections - -// KVO-compliant proxy object for section mutations -- (NSMutableArray *)sectionsProxy -{ - return [self mutableArrayValueForKey:@"sections"]; -} - -- (void)addSectionsObject:(id)section -{ - [self.sections addObject:section]; -} - -- (void)insertSections:(NSArray *)objects atIndexes:(NSIndexSet *)indexes -{ - [self.sections insertObjects:objects atIndexes:indexes]; -} - -- (void)removeSectionsAtIndexes:(NSIndexSet *)indexes -{ - [self.sections removeObjectsAtIndexes:indexes]; -} - -- (void)replaceSectionsAtIndexes:(NSIndexSet *)indexes withObjects:(NSArray *)objects -{ - [self.sections replaceObjectsAtIndexes:indexes withObjects:objects]; -} - -- (void)addSection:(RKTableSection *)section -{ - NSAssert(section, @"Cannot insert a nil section"); - section.tableController = self; - if (! section.cellMappings) { - section.cellMappings = self.cellMappings; - } - - [[self sectionsProxy] addObject:section]; -} - -- (void)removeSection:(RKTableSection *)section -{ - NSAssert(section, @"Cannot remove a nil section"); - if ([self.sections containsObject:section] && self.sectionCount == 1) { - @throw [NSException exceptionWithName:NSInvalidArgumentException - reason:@"Tables must always have at least one section" - userInfo:nil]; - } - [[self sectionsProxy] removeObject:section]; -} - -- (void)insertSection:(RKTableSection *)section atIndex:(NSUInteger)index -{ - NSAssert(section, @"Cannot insert a nil section"); - section.tableController = self; - [[self sectionsProxy] insertObject:section atIndex:index]; -} - -- (void)removeSectionAtIndex:(NSUInteger)index -{ - if (index < self.sectionCount && self.sectionCount == 1) { - @throw [NSException exceptionWithName:NSInvalidArgumentException - reason:@"Tables must always have at least one section" - userInfo:nil]; - } - [[self sectionsProxy] removeObjectAtIndex:index]; -} - -- (void)removeAllSections:(BOOL)recreateFirstSection -{ - [[self sectionsProxy] removeAllObjects]; - - if (recreateFirstSection) { - [self addSection:[RKTableSection section]]; - } -} - -- (void)removeAllSections -{ - [self removeAllSections:YES]; -} - -- (void)updateTableViewUsingBlock:(void (^)())block -{ - [self.tableView beginUpdates]; - block(); - [self.tableView endUpdates]; -} - -#pragma mark - Static Tables - -- (NSArray *)objectsWithHeaderAndFooters:(NSArray *)objects forSection:(NSUInteger)sectionIndex -{ - NSMutableArray *mutableObjects = [objects mutableCopy]; - if (sectionIndex == 0) { - if ([self.headerItems count] > 0) { - [mutableObjects insertObjects:self.headerItems atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.headerItems.count)]]; - } - if (self.emptyItem) { - [mutableObjects insertObject:self.emptyItem atIndex:0]; - } - } - - if (sectionIndex == (self.sectionCount - 1) && [self.footerItems count] > 0) { - [mutableObjects addObjectsFromArray:self.footerItems]; - } - - return [mutableObjects autorelease]; -} - -// NOTE - Everything currently needs to pass through this method to pick up header/footer rows... -- (void)loadObjects:(NSArray *)objects inSection:(NSUInteger)sectionIndex -{ - // Clear any existing error state from the table - self.error = nil; - - RKTableSection *section = [self sectionAtIndex:sectionIndex]; - section.objects = [self objectsWithHeaderAndFooters:objects forSection:sectionIndex]; - for (NSUInteger index = 0; index < [section.objects count]; index++) { - if ([self.delegate respondsToSelector:@selector(tableController:didInsertObject:atIndexPath:)]) { - [self.delegate tableController:self - didInsertObject:[section objectAtIndex:index] - atIndexPath:[NSIndexPath indexPathForRow:index inSection:sectionIndex]]; - } - } - - [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:self.defaultRowAnimation]; - - if ([self.delegate respondsToSelector:@selector(tableController:didLoadObjects:inSection:)]) { - [self.delegate tableController:self didLoadObjects:objects inSection:section]; - } - - // The load is finalized via network callbacks for - // dynamic table controllers - if (nil == self.objectLoader) { - [self didFinishLoad]; - } -} - -- (void)loadObjects:(NSArray *)objects -{ - [self loadObjects:objects inSection:0]; -} - -- (void)loadEmpty -{ - [self removeAllSections:YES]; - [self loadObjects:[NSArray array]]; -} - -- (void)loadTableItems:(NSArray *)tableItems inSection:(NSUInteger)sectionIndex -{ - for (RKTableItem *tableItem in tableItems) { - if ([tableItem.cellMapping.attributeMappings count] == 0) { - [tableItem.cellMapping addDefaultMappings]; - } - } - - [self loadObjects:tableItems inSection:sectionIndex]; -} - -- (void)loadTableItems:(NSArray *)tableItems - inSection:(NSUInteger)sectionIndex - withMapping:(RKTableViewCellMapping *)cellMapping -{ - NSAssert(tableItems, @"Cannot load a nil collection of table items"); - NSAssert(sectionIndex < self.sectionCount, @"Cannot load table items into a section that does not exist"); - NSAssert(cellMapping, @"Cannot load table items without a cell mapping"); - for (RKTableItem *tableItem in tableItems) { - tableItem.cellMapping = cellMapping; - } - [self loadTableItems:tableItems inSection:sectionIndex]; -} - -- (void)loadTableItems:(NSArray *)tableItems withMapping:(RKTableViewCellMapping *)cellMapping -{ - [self loadTableItems:tableItems inSection:0 withMapping:cellMapping]; -} - -- (void)loadTableItems:(NSArray *)tableItems -{ - [self loadTableItems:tableItems inSection:0]; -} - -#pragma mark - Network Table Loading - -- (void)loadTableFromResourcePath:(NSString *)resourcePath -{ - [self loadTableFromResourcePath:resourcePath usingBlock:nil]; -} - -- (void)loadTableFromResourcePath:(NSString *)resourcePath usingBlock:(void (^)(RKObjectLoader *loader))block -{ - NSAssert(self.objectManager, @"Cannot perform a network load without an object manager"); - RKObjectLoader *objectLoader = [self.objectManager loaderWithResourcePath:resourcePath]; - if (block) block(objectLoader); - [self loadTableWithObjectLoader:objectLoader]; -} - -#pragma mark - UITableViewDataSource methods - -- (void)tableView:(UITableView *)theTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSAssert(theTableView == self.tableView, @"tableView:commitEditingStyle:forRowAtIndexPath: invoked with inappropriate tableView: %@", theTableView); - if (self.canEditRows) { - if (editingStyle == UITableViewCellEditingStyleDelete) { - RKTableSection *section = [self.sections objectAtIndex:indexPath.section]; - [section removeObjectAtIndex:indexPath.row]; - - } else if (editingStyle == UITableViewCellEditingStyleInsert) { - // TODO: Anything we need to do here, since we do not have the object to insert? - } - } -} - -- (void)tableView:(UITableView *)theTableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destIndexPath -{ - NSAssert(theTableView == self.tableView, @"tableView:moveRowAtIndexPath:toIndexPath: invoked with inappropriate tableView: %@", theTableView); - if (self.canMoveRows) { - if (sourceIndexPath.section == destIndexPath.section) { - RKTableSection *section = [self.sections objectAtIndex:sourceIndexPath.section]; - [section moveObjectAtIndex:sourceIndexPath.row toIndex:destIndexPath.row]; - - } else { - [self.tableView beginUpdates]; - RKTableSection *sourceSection = [self.sections objectAtIndex:sourceIndexPath.section]; - id object = [[sourceSection objectAtIndex:sourceIndexPath.row] retain]; - [sourceSection removeObjectAtIndex:sourceIndexPath.row]; - - RKTableSection *destinationSection = nil; - if (destIndexPath.section < [self sectionCount]) { - destinationSection = [self.sections objectAtIndex:destIndexPath.section]; - } else { - destinationSection = [RKTableSection section]; - [self insertSection:destinationSection atIndex:destIndexPath.section]; - } - [destinationSection insertObject:object atIndex:destIndexPath.row]; - [object release]; - [self.tableView endUpdates]; - } - } -} - -#pragma mark - RKRequestDelegate & RKObjectLoaderDelegate methods - -- (void)objectLoader:(RKObjectLoader *)loader didLoadObjects:(NSArray *)objects -{ - // TODO: Could not get the KVO to work without a boolean property... - // TODO: Apply any sorting... - - if (self.sectionNameKeyPath) { - NSArray *sectionedObjects = [objects sectionsGroupedByKeyPath:self.sectionNameKeyPath]; - if ([sectionedObjects count] == 0) { - [self removeAllSections]; - } - for (NSArray *sectionOfObjects in sectionedObjects) { - NSUInteger sectionIndex = [sectionedObjects indexOfObject:sectionOfObjects]; - if (sectionIndex >= [self sectionCount]) { - [self addSection:[RKTableSection section]]; - } - [self loadObjects:sectionOfObjects inSection:sectionIndex]; - } - } else { - [self loadObjects:objects inSection:0]; - } -} - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; - if ([keyPath isEqualToString:@"sections"]) { - // No table view to inform... - if (! self.tableView) { - return; - } - - NSIndexSet *changedSectionIndexes = [change objectForKey:NSKeyValueChangeIndexesKey]; - NSAssert(changedSectionIndexes, @"Received a KVO notification for settings property without an NSKeyValueChangeIndexesKey"); - if ([[change objectForKey:NSKeyValueChangeKindKey] intValue] == NSKeyValueChangeInsertion) { - // Section(s) Inserted - [self.tableView insertSections:changedSectionIndexes withRowAnimation:self.defaultRowAnimation]; - - // TODO: Add observers on the sections objects... - - } else if ([[change objectForKey:NSKeyValueChangeKindKey] intValue] == NSKeyValueChangeRemoval) { - // Section(s) Deleted - [self.tableView deleteSections:changedSectionIndexes withRowAnimation:self.defaultRowAnimation]; - - // TODO: Remove observers on the sections objects... - } else if ([[change objectForKey:NSKeyValueChangeKindKey] intValue] == NSKeyValueChangeReplacement) { - // Section(s) Replaced - [self.tableView reloadSections:changedSectionIndexes withRowAnimation:self.defaultRowAnimation]; - - // TODO: Remove observers on the sections objects... - } - } - - // TODO: KVO should be used for managing the row level manipulations on the table view as well... -} - -#pragma mark - Managing Sections - -- (NSUInteger)sectionCount -{ - return [_sections count]; -} - -- (NSUInteger)rowCount -{ - return [[_sections valueForKeyPath:@"@sum.rowCount"] intValue]; -} - -- (RKTableSection *)sectionAtIndex:(NSUInteger)index -{ - return [_sections objectAtIndex:index]; -} - -- (NSUInteger)indexForSection:(RKTableSection *)section -{ - NSAssert(section, @"Cannot return index for a nil section"); - return [_sections indexOfObject:section]; -} - -- (RKTableSection *)sectionWithHeaderTitle:(NSString *)title -{ - for (RKTableSection *section in _sections) { - if ([section.headerTitle isEqualToString:title]) { - return section; - } - } - - return nil; -} - -- (NSUInteger)numberOfRowsInSection:(NSUInteger)index -{ - return [self sectionAtIndex:index].rowCount; -} - -#pragma mark - Cell Mappings - -- (id)objectForRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSAssert(indexPath, @"Cannot lookup object with a nil indexPath"); - RKTableSection *section = [self sectionAtIndex:indexPath.section]; - return [section objectAtIndex:indexPath.row]; -} - -#pragma mark - UITableViewDataSource methods - -- (NSString *)tableView:(UITableView *)theTableView titleForHeaderInSection:(NSInteger)section -{ - NSAssert(theTableView == self.tableView, @"tableView:titleForHeaderInSection: invoked with inappropriate tableView: %@", theTableView); - return [[_sections objectAtIndex:section] headerTitle]; -} - -- (NSString *)tableView:(UITableView *)theTableView titleForFooterInSection:(NSInteger)section -{ - NSAssert(theTableView == self.tableView, @"tableView:titleForFooterInSection: invoked with inappropriate tableView: %@", theTableView); - return [[_sections objectAtIndex:section] footerTitle]; -} - -- (BOOL)tableView:(UITableView *)theTableView canEditRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSAssert(theTableView == self.tableView, @"tableView:canEditRowAtIndexPath: invoked with inappropriate tableView: %@", theTableView); - return self.canEditRows; -} - -- (BOOL)tableView:(UITableView *)theTableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSAssert(theTableView == self.tableView, @"tableView:canMoveRowAtIndexPath: invoked with inappropriate tableView: %@", theTableView); - return self.canMoveRows; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView -{ - NSAssert(theTableView == self.tableView, @"numberOfSectionsInTableView: invoked with inappropriate tableView: %@", theTableView); - RKLogTrace(@"%@ numberOfSectionsInTableView = %d", self, self.sectionCount); - return self.sectionCount; -} - -- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section -{ - NSAssert(theTableView == self.tableView, @"tableView:numberOfRowsInSection: invoked with inappropriate tableView: %@", theTableView); - RKLogTrace(@"%@ numberOfRowsInSection:%d = %d", self, section, self.sectionCount); - return [[_sections objectAtIndex:section] rowCount]; -} - -- (NSIndexPath *)indexPathForObject:(id)object -{ - NSUInteger sectionIndex = 0; - for (RKTableSection *section in self.sections) { - NSUInteger rowIndex = 0; - for (id rowObject in section.objects) { - if ([rowObject isEqual:object]) { - return [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex]; - } - - rowIndex++; - } - sectionIndex++; - } - - return nil; -} - -- (CGFloat)tableView:(UITableView *)theTableView heightForHeaderInSection:(NSInteger)sectionIndex -{ - NSAssert(theTableView == self.tableView, @"heightForHeaderInSection: invoked with inappropriate tableView: %@", theTableView); - if ([self.delegate respondsToSelector:@selector(tableController:heightForHeaderInSection:)]) { - return [self.delegate tableController:self heightForHeaderInSection:sectionIndex]; - } else { - RKTableSection *section = [self sectionAtIndex:sectionIndex]; - return section.headerHeight; - } -} - -- (CGFloat)tableView:(UITableView *)theTableView heightForFooterInSection:(NSInteger)sectionIndex -{ - NSAssert(theTableView == self.tableView, @"heightForFooterInSection: invoked with inappropriate tableView: %@", theTableView); - if ([self.delegate respondsToSelector:@selector(tableController:heightForFooterInSection:)]) { - return [self.delegate tableController:self heightForFooterInSection:sectionIndex]; - } else { - RKTableSection *section = [self sectionAtIndex:sectionIndex]; - return section.footerHeight; - } -} - -- (UIView *)tableView:(UITableView *)theTableView viewForHeaderInSection:(NSInteger)sectionIndex -{ - NSAssert(theTableView == self.tableView, @"viewForHeaderInSection: invoked with inappropriate tableView: %@", theTableView); - RKTableSection *section = [self sectionAtIndex:sectionIndex]; - return section.headerView; -} - -- (UIView *)tableView:(UITableView *)theTableView viewForFooterInSection:(NSInteger)sectionIndex -{ - NSAssert(theTableView == self.tableView, @"viewForFooterInSection: invoked with inappropriate tableView: %@", theTableView); - RKTableSection *section = [self sectionAtIndex:sectionIndex]; - return section.footerView; -} - -- (BOOL)isConsideredEmpty -{ - NSUInteger nonRowItemsCount = [self.headerItems count] + [self.footerItems count]; - nonRowItemsCount += self.emptyItem ? 1 : 0; - BOOL isEmpty = (self.rowCount - nonRowItemsCount) == 0; - RKLogTrace(@"Determined isConsideredEmpty = %@. self.rowCount = %d with %d nonRowItems in the table", isEmpty ? @"YES" : @"NO", self.rowCount, nonRowItemsCount); - return isEmpty; -} - -@end diff --git a/Code/UI/RKTableItem.h b/Code/UI/RKTableItem.h deleted file mode 100644 index 11df234c1b..0000000000 --- a/Code/UI/RKTableItem.h +++ /dev/null @@ -1,156 +0,0 @@ -// -// RKTableItem.h -// RestKit -// -// Created by Blake Watters on 8/8/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 -#import "RKMutableBlockDictionary.h" - -@class RKTableViewCellMapping; - -/** - A generic class for defining vanilla table items when - you do not have local domain items for your table rows. This - is used to implement simple static tables quickly. - */ -@interface RKTableItem : NSObject - -@property (nonatomic, retain) NSString *text; -@property (nonatomic, retain) NSString *detailText; -@property (nonatomic, retain) UIImage *image; -@property (nonatomic, retain) NSString *URL; - -/** - A dictionary reference for storing ad-hoc KVC data useful in building - table items that require extra information beyond the concrete properties - available on the table item. - - Values stored within the userData dictionary can be used to map arbitrary data - into your table cells without resorting to subclassing RKTableItem: - [tableItem.userData setValue:userAvatarImage forKey:@"userAvatarImage"]; - [tableItem.cellMapping mapKeyPath:@"userData.userAvatarImage" toKeyPath:@"imageView.image"]; - - Note that this is an instance of RKMutableBlockDictionary -- a dictionary capable of - storing executable block values that will be resolved at mapping time. - - For convenience, you can also perform key-value coding operations on instances of RKTableItem - themselves. Any undefined KVC operations will be passed through to the underlying - userData property. This permits you to have alignment on your keyPaths between the - table item and your target cells when defining mappings. Considering the above examples, - we could also write the following code instead: - [tableItem setValue:userAvatarImage forKey:@"userAvatarImage"]; - [tableItem.cellMapping mapKeyPath:@"userAvatarImage" toKeyPath:@"imageView.image"]; - - Or more concretely, if we have a group of properties such as title, description, and publishedDate - on our UITableViewCell destination class, we can configure it quickly via: - [tableItem setValue:@"Some Title" forKey:@"title"]; - [tableItem setValue:@"This is an awesome movie." forKey:@"description"]; - [tableItem setValue:[NSDate date] forKey:@"publishedDate"]; - [tableItem.cellMapping mapAttributes:@"title", @"description", @"publishedDate", nil]; - - @see RKMutableBlockDictionary - */ -@property (nonatomic, retain) RKMutableBlockDictionary *userData; - -/** - Informal protocol implementation. Any object that responds to the `cellMapping` message - and returns an RKTableViewCellMapping will be mapped into a table view cell according to - the rules in the mapping. - - Generally table items are mapped using class -> cell mapping semantics. This is configured - via invocation of [RKTableController mapObjectClass:toTableCellClass:]. Default mappings for - RKTableItem instances are configured on your behalf when you invoke the [RKTableView loadTableItems:] - family of methods. - - If you assign a cell mapping to an individual table item then the assigned cell mapping will - be used instead of the class configured 'default' mapping. - - **Default**: nil - */ -@property (nonatomic, retain) RKTableViewCellMapping *cellMapping; - -/** - Return a new array of RKTableItem instances given a nil terminated list of strings. - Each table item will have the text property set to the string provided. - */ -+ (NSArray *)tableItemsFromStrings:(NSString *)firstString, ... NS_REQUIRES_NIL_TERMINATION; - -/** - Returns a new table item - */ -+ (id)tableItem; - -/** - Initialize a new table item and yield it to the block for configuration - */ -+ (id)tableItemUsingBlock:(void (^)(RKTableItem *tableItem))block; - -/** - Initialize a new table item with the specified text - */ -+ (id)tableItemWithText:(NSString *)text; - -/** - Initialize a new table item with the specified text & details text - */ -+ (id)tableItemWithText:(NSString *)text detailText:(NSString *)detailText; - -/** - Construct a new auto-released table item with the specified text, detailText and image - properties. - */ -+ (id)tableItemWithText:(NSString *)text detailText:(NSString *)detailText image:(UIImage *)image; - -/** - Construct a new table item with the specified text and yield it to the block for configuration. - This is a convenient mechanism for quickly constructing table items that have been subclassed. - - For example: - - NSArray *tableItems = [NSArray arrayWithObjects:[MyTableItem tableItemWithText:@"Foo" - usingBlock:^(RKTableItem *tableItem) { - [(MyTableItem *)tableItem setURL:@"app://whatever"]; - }], ...]; - */ -+ (id)tableItemWithText:(NSString *)text usingBlock:(void (^)(RKTableItem *tableItem))block; - -/** - Constructs a new table item with the specified text and URL. This is useful if you are working - with Three20 or another library that provides URL dispatching. - */ -+ (id)tableItemWithText:(NSString *)text URL:(NSString *)URL; - -/** - Construct a new table item with the specified cell mapping - */ -+ (id)tableItemWithCellMapping:(RKTableViewCellMapping *)cellMapping; - -/** - Construct a new table item that will map into an instance of the specified - UITableViewCell subclass. This is helpful if you are constructing a static table - with a handful of different cells and don't need to configure a full cell mapping. - - When invoked, an instance of RKTableViewCellMapping will be created on your behalf - and assigned to the cellMapping property. The objectClass of the cellMapping will be - set to the subclass of UITableViewCell you provided. - - @param tableViewCellSubclass A subclass of UITableViewCell to map this item into - */ -+ (id)tableItemWithCellClass:(Class)tableViewCellSubclass; - -@end diff --git a/Code/UI/RKTableItem.m b/Code/UI/RKTableItem.m deleted file mode 100644 index 8d130e94d8..0000000000 --- a/Code/UI/RKTableItem.m +++ /dev/null @@ -1,158 +0,0 @@ -// -// RKTableItem.m -// RestKit -// -// Created by Blake Watters on 8/8/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 "RKTableItem.h" -#import "RKTableViewCellMapping.h" - -@implementation RKTableItem - -@synthesize text = _text; -@synthesize detailText = _detailText; -@synthesize image = _image; -@synthesize cellMapping = _cellMapping; -@synthesize URL = _URL; -@synthesize userData = _userData; - -+ (NSArray *)tableItemsFromStrings:(NSString *)firstString, ... -{ - va_list args; - va_start(args, firstString); - NSMutableArray *tableItems = [NSMutableArray array]; - for (NSString *string = firstString; string != nil; string = va_arg(args, NSString *)) { - RKTableItem *tableItem = [RKTableItem new]; - tableItem.text = string; - [tableItems addObject:tableItem]; - [tableItem release]; - } - va_end(args); - - return [NSArray arrayWithArray:tableItems]; -} - -+ (id)tableItem -{ - return [[self new] autorelease]; -} - -+ (id)tableItemUsingBlock:(void (^)(RKTableItem *))block -{ - RKTableItem *tableItem = [self tableItem]; - block(tableItem); - return tableItem; -} - -+ (id)tableItemWithText:(NSString *)text -{ - return [self tableItemUsingBlock:^(RKTableItem *tableItem) { - tableItem.text = text; - }]; -} - -+ (id)tableItemWithText:(NSString *)text detailText:(NSString *)detailText -{ - return [self tableItemUsingBlock:^(RKTableItem *tableItem) { - tableItem.text = text; - tableItem.detailText = detailText; - }]; -} - -+ (id)tableItemWithText:(NSString *)text detailText:(NSString *)detailText image:(UIImage *)image -{ - RKTableItem *tableItem = [self new]; - tableItem.text = text; - tableItem.detailText = detailText; - tableItem.image = image; - - return [tableItem autorelease]; -} - -+ (id)tableItemWithText:(NSString *)text usingBlock:(void (^)(RKTableItem *))block -{ - RKTableItem *tableItem = [[self new] autorelease]; - tableItem.text = text; - block(tableItem); - return tableItem; -} - -+ (id)tableItemWithText:(NSString *)text URL:(NSString *)URL -{ - RKTableItem *tableItem = [self tableItem]; - tableItem.text = text; - tableItem.URL = URL; - return tableItem; -} - -+ (id)tableItemWithCellMapping:(RKTableViewCellMapping *)cellMapping -{ - RKTableItem *tableItem = [self tableItem]; - tableItem.cellMapping = cellMapping; - - return tableItem; -} - -+ (id)tableItemWithCellClass:(Class)tableViewCellSubclass -{ - RKTableItem *tableItem = [self tableItem]; - tableItem.cellMapping = [RKTableViewCellMapping cellMapping]; - tableItem.cellMapping.cellClass = tableViewCellSubclass; - - return tableItem; -} - -- (id)init -{ - self = [super init]; - if (self) { - _userData = [RKMutableBlockDictionary new]; - _cellMapping = [RKTableViewCellMapping new]; - } - - return self; -} - -- (void)dealloc -{ - [_text release]; - [_detailText release]; - [_image release]; - [_cellMapping release]; - [_userData release]; - - [super dealloc]; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p text=%@, detailText=%@, image=%p>", NSStringFromClass([self class]), self, self.text, self.detailText, self.image]; -} - -#pragma mark - User Data KVC Proxy - -- (void)setValue:(id)value forUndefinedKey:(NSString *)key -{ - [self.userData setValue:value ? value : [NSNull null] forKey:key]; -} - -- (id)valueForUndefinedKey:(NSString *)key -{ - return [self.userData valueForKey:key]; -} - -@end diff --git a/Code/UI/RKTableSection.h b/Code/UI/RKTableSection.h deleted file mode 100644 index da40f5e215..0000000000 --- a/Code/UI/RKTableSection.h +++ /dev/null @@ -1,59 +0,0 @@ -// -// RKTableViewSection.h -// RestKit -// -// Created by Blake Watters on 8/2/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 -#import "RKObjectMapping.h" -#import "RKTableViewCellMappings.h" - -@class RKTableController; - -@interface RKTableSection : NSObject - -// Basics -@property (nonatomic, assign) RKTableController *tableController; -@property (nonatomic, readonly) UITableView *tableView; - -// Object Mapping Table Stuff -@property (nonatomic, retain) NSArray *objects; -@property (nonatomic, retain) RKTableViewCellMappings *cellMappings; - -// Header & Footer Views, etc. -@property (nonatomic, retain) NSString *headerTitle; -@property (nonatomic, retain) NSString *footerTitle; -@property (nonatomic, assign) CGFloat headerHeight; -@property (nonatomic, assign) CGFloat footerHeight; -@property (nonatomic, retain) UIView *headerView; -@property (nonatomic, retain) UIView *footerView; - -// number of cells in the section -@property (nonatomic, readonly) NSUInteger rowCount; - -+ (id)section; -+ (id)sectionUsingBlock:(void (^)(RKTableSection *))block; -+ (id)sectionForObjects:(NSArray *)objects withMappings:(RKTableViewCellMappings *)cellMappings; - -- (id)objectAtIndex:(NSUInteger)rowIndex; -- (void)addObject:(id)object; -- (void)insertObject:(id)object atIndex:(NSUInteger)index; -- (void)removeObjectAtIndex:(NSUInteger)index; -- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)object; -- (void)moveObjectAtIndex:(NSUInteger)sourceIndex toIndex:(NSUInteger)destinationIndex; - -@end diff --git a/Code/UI/RKTableSection.m b/Code/UI/RKTableSection.m deleted file mode 100644 index 1957d25c8d..0000000000 --- a/Code/UI/RKTableSection.m +++ /dev/null @@ -1,173 +0,0 @@ -// -// RKTableViewSection.m -// RestKit -// -// Created by Blake Watters on 8/2/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 "RKTableSection.h" -#import "RKTableController.h" -#import "RKTableViewCellMapping.h" -#import "RKLog.h" - -// Define logging component -#undef RKLogComponent -#define RKLogComponent lcl_cRestKitUI - -@implementation RKTableSection - -@synthesize objects = _objects; -@synthesize cellMappings = _cellMappings; -@synthesize tableController = _tableController; -@synthesize headerTitle = _headerTitle; -@synthesize footerTitle = _footerTitle; -@synthesize headerHeight = _headerHeight; -@synthesize footerHeight = _footerHeight; -@synthesize headerView = _headerView; -@synthesize footerView = _footerView; - -+ (id)section -{ - return [[self new] autorelease]; -} - -+ (id)sectionUsingBlock:(void (^)(RKTableSection *))block -{ - RKTableSection *section = [self section]; - block(section); - return section; -} - -+ (id)sectionForObjects:(NSArray *)objects withMappings:(RKTableViewCellMappings *)cellMappings -{ - return [self sectionUsingBlock:^(RKTableSection *section) { - section.objects = objects; - section.cellMappings = cellMappings; - }]; -} - -- (id)init -{ - self = [super init]; - if (self) { - _objects = [NSMutableArray new]; - _headerHeight = 0; - _footerHeight = 0; - } - - return self; -} - -- (void)dealloc -{ - [_objects release]; - [_cellMappings release]; - [_headerTitle release]; - [_footerTitle release]; - [_headerView release]; - [_footerView release]; - [super dealloc]; -} - -- (void)setObjects:(NSArray *)objects -{ - if (! [objects isMemberOfClass:[NSMutableArray class]]) { - NSMutableArray *mutableObjects = [objects mutableCopy]; - [_objects release]; - _objects = mutableObjects; - } else { - [objects retain]; - [_objects release]; - _objects = (NSMutableArray *)objects; - } -} - -- (NSUInteger)rowCount -{ - return [_objects count]; -} - -- (id)objectAtIndex:(NSUInteger)rowIndex -{ - return [_objects objectAtIndex:rowIndex]; -} - -- (UITableView *)tableView -{ - return _tableController.tableView; -} - -- (void)addObject:(id)object -{ - return [self insertObject:object atIndex:[_objects count]]; -} - -- (void)insertObject:(id)object atIndex:(NSUInteger)index -{ - [(NSMutableArray*)_objects insertObject:object atIndex:index]; - - NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index - inSection:[_tableController indexForSection:self]]; - [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] - withRowAnimation:_tableController.defaultRowAnimation]; - - if ([_tableController.delegate respondsToSelector:@selector(tableController:didInsertObject:atIndexPath:)]) { - [_tableController.delegate tableController:_tableController didInsertObject:object atIndexPath:indexPath]; - } -} - -- (void)removeObjectAtIndex:(NSUInteger)index -{ - id object = [self objectAtIndex:index]; - [(NSMutableArray *)_objects removeObjectAtIndex:index]; - - NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index - inSection:[_tableController indexForSection:self]]; - [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] - withRowAnimation:_tableController.defaultRowAnimation]; - - if ([_tableController.delegate respondsToSelector:@selector(tableController:didDeleteObject:atIndexPath:)]) { - [_tableController.delegate tableController:_tableController didDeleteObject:object atIndexPath:indexPath]; - } -} - -- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)object -{ - [(NSMutableArray *)_objects replaceObjectAtIndex:index withObject:object]; - - NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index - inSection:[_tableController indexForSection:self]]; - [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] - withRowAnimation:_tableController.defaultRowAnimation]; - - if ([_tableController.delegate respondsToSelector:@selector(tableController:didUpdateObject:atIndexPath:)]) { - [_tableController.delegate tableController:_tableController didUpdateObject:object atIndexPath:indexPath]; - } -} - -- (void)moveObjectAtIndex:(NSUInteger)sourceIndex toIndex:(NSUInteger)destinationIndex -{ - [self.tableView beginUpdates]; - id object = [[self objectAtIndex:sourceIndex] retain]; - [self removeObjectAtIndex:sourceIndex]; - [self insertObject:object atIndex:destinationIndex]; - [object release]; - [self.tableView endUpdates]; - - // TODO: Should use moveRowAtIndexPath: when on iOS 5 -} - -@end diff --git a/Code/UI/RKTableViewCellMapping.h b/Code/UI/RKTableViewCellMapping.h deleted file mode 100644 index 40495fe43f..0000000000 --- a/Code/UI/RKTableViewCellMapping.h +++ /dev/null @@ -1,235 +0,0 @@ -// -// RKTableViewCellMapping.h -// RestKit -// -// Created by Blake Watters on 8/4/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 -#import "RKObjectMapping.h" -#import "RKTableCellBlockTypes.h" - -/** - Defines a RestKit object mapping suitable for mapping generic - objects into UITableViewCell derived classes or cells loaded from - NIBs. The cell mapping leverages RestKit's object mapping engine to - dynamically map keyPaths in your object model into properties on the - table cell view. - - Cell mappings are used to drive table view cells within an RKTableController - derived class. The cell mapping does not require any specific implementation - on the target cell classes beyond exposure of the configurable UIView's via - KVC properties. - - @see RKTableController - */ -@interface RKTableViewCellMapping : RKObjectMapping - -/** - The UITableViewCell subclass that this mapping will target. This - is an alias for the objectClass property defined on the base mapping - provided here to make things more explicit. - - @default [GGImageButtonTableViewCell class] - @see objectClass - */ -@property (nonatomic, assign) Class cellClass; - -/** - Convenience accessor for setting the cellClass attribute via a string - rather than a class instance. This will typically save you from having - to #import the header file for your target cells in your table view controller - - @default @"GGImageButtonTableViewCell" - @see cellClass - */ -@property (nonatomic, assign) NSString *cellClassName; - -/** - A reuse identifier for cells created using this mapping. These cells will be - dequeued and reused within the table view for optimal performance. By default, - a reuseIdentifier is set for you when you assign an object class to the mapping. - You can override this behavior if you have multiple cells representing the same types - of objects within the table view and need to pool the cells differently. - - @default NSStringFromClass(self.objectClass) - */ -@property (nonatomic, retain) NSString *reuseIdentifier; - -/** - A Boolean value that determines whether the cell mapping manages basic cell - attributes (accessoryType, selectionStyle, etc.) or defers to a Storyboard/XIB - for defining basic cell attributes. - - Setting the accessoryType or selectionStyle will set the value to YES. - - **Default**: NO - */ -@property (nonatomic, assign) BOOL managesCellAttributes; - -/** - The cell style to use for cells created with this mapping - - @default UITableViewCellStyleDefault - */ -@property (nonatomic, assign) UITableViewCellStyle style; - -/** - The cell accessory type to use for cells created with this mapping - - @default UITableViewCellAccessoryNone - */ -@property (nonatomic, assign) UITableViewCellAccessoryType accessoryType; - -/** - The cell selection style to use for cells created with this mapping - - @default UITableViewCellSelectionStyleBlue - */ -@property (nonatomic, assign) UITableViewCellSelectionStyle selectionStyle; - -/** - Whether the tableController should call deselectRowAtIndexPath:animated: - on the tableView when a cell is selected. - - @default YES - */ -@property (nonatomic, assign) BOOL deselectsRowOnSelection; - -/** - The row height to use for cells created with this mapping. - Use of this property requires that RKTableController instance you are - using the mapping to build cells for has been configured with variableHeightRows = YES - - This value is mutually exclusive of the heightOfCellForObjectAtIndexPath property - and will be ignored if you assign a block to perform dynamic row height calculations. - - **Default**: 44 - */ -@property (nonatomic, assign) CGFloat rowHeight; - -/** @name Cell Events **/ - -/** - Invoked when the user has touched a cell corresponding to an object. The block - is invoked with a reference to both the UITableViewCell that was touched and the - object the cell is representing. - */ -@property (nonatomic, copy) RKTableCellForObjectAtIndexPathBlock onSelectCellForObjectAtIndexPath; - -/** - Invoked when the user has touched a cell configured with this mapping. The block is invoked - without any arguments. This is useful for one-off touch events where you do not care about - the content in which the selection took place. - - @see onSelectCellForObjectAtIndexPath - */ -@property (nonatomic, copy) RKTableVoidBlock onSelectCell; - -/** - A block to invoke when a table view cell created with this mapping is going to appear in the table. - The block will be invoked with the UITableViewCell, an id reference to the mapped object being - represented in the cell, and the NSIndexPath for the row position the cell will be appearing at. - - This is a good moment to perform any customization to the cell before it becomes visible in the table view. - */ -@property (nonatomic, copy) RKTableCellForObjectAtIndexPathBlock onCellWillAppearForObjectAtIndexPath; - -/** - A block to invoke when the table view is measuring the height of the UITableViewCell. - The block will be invoked with the UITableViewCell, an id reference to the mapped object being - represented in the cell, and the NSIndexPath for the row position the cell will be appearing at. - */ -@property (nonatomic, copy) RKTableHeightOfCellForObjectAtIndexPathBlock heightOfCellForObjectAtIndexPath; - -/** - A block to invoke when the accessory button for a given cell is tapped by the user. - The block will be invoked with the UITableViewCell, an id reference to the mapped object being - represented in the cell, and the NSIndexPath for the row position the cell will be appearing at. - */ -@property (nonatomic, copy) RKTableCellForObjectAtIndexPathBlock onTapAccessoryButtonForObjectAtIndexPath; - -/** - A block to invoke when the table view is determining the title for the delete confirmation button. - The block will be invoked with the UITableViewCell, an id reference to the mapped object being - represented in the cell, and the NSIndexPath for the row position the cell will be appearing at. - */ -@property (nonatomic, copy) RKTableStringForObjectAtIndexPathBlock titleForDeleteButtonForObjectAtIndexPath; - -/** - A block to invoke when the table view is determining the editing style for a given row. - The block will be invoked with the UITableViewCell, an id reference to the mapped object being - represented in the cell, and the NSIndexPath for the row position the cell will be appearing at. - */ -@property (nonatomic, copy) RKTableCellEditingStyleForObjectAtIndexPathBlock editingStyleForObjectAtIndexPath; - -// TODO: Docs... -@property (nonatomic, copy) RKTableTargetIndexPathForMoveBlock targetIndexPathForMove; - -/** - Returns a new auto-released mapping targeting UITableViewCell - */ -+ (id)cellMapping; - -/** - Returns a new auto-released mapping targeting UITableViewCell with the specified reuseIdentifier - */ -+ (id)cellMappingForReuseIdentifier:(NSString *)reuseIdentifier; - -/** - Creates and returns an RKTableCellMapping instance configured with the default cell mappings. - - @return An RKTableCellMapping instance with default mappings applied. - @see [RKTableCellMapping addDefaultMappings] - */ -+ (id)defaultCellMapping; - -/** - Returns a new auto-released object mapping targeting UITableViewCell. The mapping - will be yielded to the block for configuration. - */ -+ (id)cellMappingUsingBlock:(void (^)(RKTableViewCellMapping *cellMapping))block; - -/** - Sets up default mappings connecting common properties to their UITableViewCell counterparts as follows: - - [self mapKeyPath:@"text" toAttribute:@"textLabel.text"]; - [self mapKeyPath:@"detailText" toAttribute:@"detailTextLabel.text"]; - [self mapKeyPath:@"image" toAttribute:@"imageView.image"]; - - These properties are exposed on the RKTableItem class for convenience in quickly building static - table views/ - - @see RKTableItem - */ -- (void)addDefaultMappings; - -/** - Configure a block to be invoked whenever a cell is prepared for use with this mapping. - The block will be invoked each time a cell is either initialized or dequeued for reuse. - */ -- (void)addPrepareCellBlock:(void (^)(UITableViewCell *cell))block; -@property (nonatomic, readonly) NSArray *prepareCellBlocks; - -/** @name Configuring Control Actions */ -// TODO: Docs!!! - -- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents toControlAtKeyPath:(NSString *)keyPath; -- (void)addTarget:(id)target action:(SEL)action forTouchEventToControlAtKeyPath:(NSString *)keyPath; -- (void)addBlockAction:(void (^)(id sender))block forControlEvents:(UIControlEvents)controlEvents toControlAtKeyPath:(NSString *)keyPath; -- (void)addBlockAction:(void (^)(id sender))block forTouchEventToControlAtKeyPath:(NSString *)keyPath; - -@end diff --git a/Code/UI/RKTableViewCellMapping.m b/Code/UI/RKTableViewCellMapping.m deleted file mode 100644 index 4f57ff0d6c..0000000000 --- a/Code/UI/RKTableViewCellMapping.m +++ /dev/null @@ -1,295 +0,0 @@ -// -// RKTableViewCellMapping.m -// RestKit -// -// Created by Blake Watters on 8/4/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 "RKTableViewCellMapping.h" -#import "RKLog.h" - -// Define logging component -#undef RKLogComponent -#define RKLogComponent lcl_cRestKitUI - -/** - A simple class for wrapping blocks into target/action - invocations that can be used with UIControl events - */ -typedef void(^RKControlBlockActionBlock)(id sender); -@interface RKControlBlockAction : NSObject { -@private - RKControlBlockActionBlock _actionBlock; -} - -@property (nonatomic, readonly) SEL actionSelector; - -+ (id)actionWithBlock:(void(^)(id sender))block; -- (id)initWithBlock:(void(^)(id sender))block; - -/** - The target action to use when wrapping a block - */ -- (void)actionForControlEvent:(id)sender; - -@end - -@implementation RKControlBlockAction - -+ (id)actionWithBlock:(void(^)(id sender))block -{ - return [[[self alloc] initWithBlock:block] autorelease]; -} - -- (id)initWithBlock:(void(^)(id sender))block -{ - self = [self init]; - if (self) { - _actionBlock = Block_copy(block); - } - - return self; -} - -- (void)actionForControlEvent:(id)sender -{ - _actionBlock(sender); -} - -- (SEL)actionSelector -{ - return @selector(actionForControlEvent:); -} - -- (void)dealloc -{ - Block_release(_actionBlock); - [super dealloc]; -} - -@end - -@interface RKTableViewCellMapping () -@property (nonatomic, retain) NSMutableArray *mutablePrepareCellBlocks; -@end - -@implementation RKTableViewCellMapping - -@synthesize reuseIdentifier = _reuseIdentifier; -@synthesize style = _style; -@synthesize accessoryType = _accessoryType; -@synthesize selectionStyle = _selectionStyle; -@synthesize onSelectCellForObjectAtIndexPath = _onSelectCellForObjectAtIndexPath; -@synthesize onSelectCell = _onSelectCell; -@synthesize onCellWillAppearForObjectAtIndexPath = _onCellWillAppearForObjectAtIndexPath; -@synthesize heightOfCellForObjectAtIndexPath = _heightOfCellForObjectAtIndexPath; -@synthesize onTapAccessoryButtonForObjectAtIndexPath = _onTapAccessoryButtonForObjectAtIndexPath; -@synthesize titleForDeleteButtonForObjectAtIndexPath = _titleForDeleteButtonForObjectAtIndexPath; -@synthesize editingStyleForObjectAtIndexPath = _editingStyleForObjectAtIndexPath; -@synthesize targetIndexPathForMove = _targetIndexPathForMove; -@synthesize rowHeight = _rowHeight; -@synthesize deselectsRowOnSelection = _deselectsRowOnSelection; -@synthesize managesCellAttributes = _managesCellAttributes; -@synthesize mutablePrepareCellBlocks = _mutablePrepareCellBlocks; - -+ (id)cellMapping -{ - return [self mappingForClass:[UITableViewCell class]]; -} - -+ (id)cellMappingForReuseIdentifier:(NSString *)reuseIdentifier -{ - RKTableViewCellMapping *cellMapping = [self cellMapping]; - cellMapping.reuseIdentifier = reuseIdentifier; - return cellMapping; -} - -+ (id)defaultCellMapping -{ - RKTableViewCellMapping *cellMapping = [self cellMapping]; - [cellMapping addDefaultMappings]; - return cellMapping; -} - -+ (id)cellMappingUsingBlock:(void (^)(RKTableViewCellMapping *))block -{ - RKTableViewCellMapping *cellMapping = [self cellMapping]; - block(cellMapping); - return cellMapping; -} - -- (id)init -{ - self = [super init]; - if (self) { - self.cellClass = [UITableViewCell class]; - self.style = UITableViewCellStyleDefault; - self.managesCellAttributes = NO; - _accessoryType = UITableViewCellAccessoryNone; - _selectionStyle = UITableViewCellSelectionStyleBlue; - self.rowHeight = 44; - self.deselectsRowOnSelection = YES; - self.mutablePrepareCellBlocks = [NSMutableArray array]; - } - - return self; -} - -- (void)addDefaultMappings -{ - [self addAttributeMappingsFromDictionary:@{ - @"text": @"textLabel.text", - @"detailText": @"detailTextLabel.text", - @"image": @"imageView.image", - }]; -} - -- (void)dealloc -{ - [_reuseIdentifier release]; - [_mutablePrepareCellBlocks release]; - Block_release(_onSelectCell); - Block_release(_onSelectCellForObjectAtIndexPath); - Block_release(_onCellWillAppearForObjectAtIndexPath); - Block_release(_heightOfCellForObjectAtIndexPath); - Block_release(_onTapAccessoryButtonForObjectAtIndexPath); - Block_release(_titleForDeleteButtonForObjectAtIndexPath); - Block_release(_editingStyleForObjectAtIndexPath); - Block_release(_targetIndexPathForMove); - [super dealloc]; -} - -- (id)copyWithZone:(NSZone *)zone -{ - RKTableViewCellMapping *copy = [super copyWithZone:zone]; - copy.reuseIdentifier = self.reuseIdentifier; - copy.style = self.style; - copy.accessoryType = self.accessoryType; - copy.selectionStyle = self.selectionStyle; - copy.onSelectCellForObjectAtIndexPath = self.onSelectCellForObjectAtIndexPath; - copy.onSelectCell = self.onSelectCell; - copy.onCellWillAppearForObjectAtIndexPath = self.onCellWillAppearForObjectAtIndexPath; - copy.heightOfCellForObjectAtIndexPath = self.heightOfCellForObjectAtIndexPath; - copy.onTapAccessoryButtonForObjectAtIndexPath = self.onTapAccessoryButtonForObjectAtIndexPath; - copy.titleForDeleteButtonForObjectAtIndexPath = self.titleForDeleteButtonForObjectAtIndexPath; - copy.editingStyleForObjectAtIndexPath = self.editingStyleForObjectAtIndexPath; - copy.targetIndexPathForMove = self.targetIndexPathForMove; - copy.rowHeight = self.rowHeight; - - @synchronized(_mutablePrepareCellBlocks) { - for (void (^block)(UITableViewCell *) in _mutablePrepareCellBlocks) { - void (^blockCopy)(UITableViewCell *cell) = [block copy]; - [copy addPrepareCellBlock:blockCopy]; - [blockCopy release]; - } - } - - return copy; -} - -- (void)setSelectionStyle:(UITableViewCellSelectionStyle)selectionStyle -{ - self.managesCellAttributes = YES; - _selectionStyle = selectionStyle; -} - -- (void)setAccessoryType:(UITableViewCellAccessoryType)accessoryType -{ - self.managesCellAttributes = YES; - _accessoryType = accessoryType; -} - -- (void)setObjectClass:(Class)objectClass -{ - NSAssert([objectClass isSubclassOfClass:[UITableViewCell class]], @"Cell mappings can only target classes that inherit from UITableViewCell"); - [super setObjectClass:objectClass]; -} - -- (void)setCellClass:(Class)cellClass -{ - [self setObjectClass:cellClass]; -} - -- (NSString *)cellClassName -{ - return NSStringFromClass(self.cellClass); -} - -- (void)setCellClassName:(NSString *)cellClassName -{ - self.cellClass = NSClassFromString(cellClassName); -} - -- (Class)cellClass -{ - return [self objectClass]; -} - -- (NSString *)reuseIdentifier -{ - return _reuseIdentifier ? _reuseIdentifier : NSStringFromClass(self.objectClass); -} - -#pragma mark - Control Action Helpers - -- (void)addPrepareCellBlock:(void (^)(UITableViewCell *cell))block -{ - void (^blockCopy)(UITableViewCell *cell) = [block copy]; - [self.mutablePrepareCellBlocks addObject:blockCopy]; - [blockCopy release]; -} - -- (NSArray *)prepareCellBlocks -{ - return [NSArray arrayWithArray:self.mutablePrepareCellBlocks]; -} - -- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents toControlAtKeyPath:(NSString *)keyPath -{ - [self addPrepareCellBlock:^(UITableViewCell *cell) { - UIControl *control = [cell valueForKeyPath:keyPath]; - if (control) { - [control addTarget:target action:action forControlEvents:controlEvents]; - } else { - // TODO: Logging... - } - }]; -} - -- (void)addTarget:(id)target action:(SEL)action forTouchEventToControlAtKeyPath:(NSString *)keyPath -{ - [self addTarget:target action:action forControlEvents:UIControlEventTouchUpInside toControlAtKeyPath:keyPath]; -} - -- (void)addBlockAction:(void (^)(id sender))block forControlEvents:(UIControlEvents)controlEvents toControlAtKeyPath:(NSString *)keyPath -{ - [self addPrepareCellBlock:^(UITableViewCell *cell) { - RKControlBlockAction *blockAction = [RKControlBlockAction actionWithBlock:block]; - UIControl *control = [cell valueForKeyPath:keyPath]; - if (control) { - [control addTarget:blockAction action:blockAction.actionSelector forControlEvents:controlEvents]; - } else { - // TODO: Logging... - } - }]; -} - -- (void)addBlockAction:(void (^)(id sender))block forTouchEventToControlAtKeyPath:(NSString *)keyPath -{ - [self addBlockAction:block forControlEvents:UIControlEventTouchUpInside toControlAtKeyPath:keyPath]; -} - -@end diff --git a/Code/UI/RKTableViewCellMappings.h b/Code/UI/RKTableViewCellMappings.h deleted file mode 100644 index 6060d05540..0000000000 --- a/Code/UI/RKTableViewCellMappings.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// RKTableViewCellMappings.h -// RestKit -// -// Created by Blake Watters on 8/9/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 "RKTableViewCellMapping.h" - -@interface RKTableViewCellMappings : NSObject { - @private - NSMutableDictionary *_cellMappings; -} - -+ (id)cellMappings; -- (void)setCellMapping:(RKTableViewCellMapping *)cellMapping forClass:(Class)objectClass; -- (RKTableViewCellMapping *)cellMappingForClass:(Class)objectClass; -- (RKTableViewCellMapping *)cellMappingForObject:(id)object; - -@end diff --git a/Code/UI/RKTableViewCellMappings.m b/Code/UI/RKTableViewCellMappings.m deleted file mode 100644 index 85837c08fd..0000000000 --- a/Code/UI/RKTableViewCellMappings.m +++ /dev/null @@ -1,79 +0,0 @@ -// -// RKTableViewCellMappings.m -// RestKit -// -// Created by Blake Watters on 8/9/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 "RKTableViewCellMappings.h" - -@implementation RKTableViewCellMappings - -+ (id)cellMappings -{ - return [[self new] autorelease]; -} - -- (id)init -{ - self = [super init]; - if (self) { - _cellMappings = [NSMutableDictionary new]; - } - - return self; -} - -- (void)setCellMapping:(RKTableViewCellMapping *)cellMapping forClass:(Class)objectClass -{ - if ([_cellMappings objectForKey:objectClass]) { - @throw [NSException exceptionWithName:NSInvalidArgumentException - reason:[NSString stringWithFormat:@"A tableViewCell mapping has already been registered for objects of type '%@'", NSStringFromClass(objectClass)] - userInfo:nil]; - } - - [_cellMappings setObject:cellMapping forKey:(id)objectClass]; -} - -- (RKTableViewCellMapping *)cellMappingForClass:(Class)objectClass -{ - // Exact match - RKTableViewCellMapping *cellMapping = [_cellMappings objectForKey:objectClass]; - if (cellMapping) return cellMapping; - - // Subclass match - for (Class cellClass in _cellMappings) { - if ([objectClass isSubclassOfClass:cellClass]) { - return [_cellMappings objectForKey:cellClass]; - } - } - - return nil; -} - -- (RKTableViewCellMapping *)cellMappingForObject:(id)object -{ - if ([object respondsToSelector:@selector(cellMapping)]) { - // TODO: Trace logging... - // TODO: This needs unit test coverage on the did select row case... - RKTableViewCellMapping *cellMapping = [object cellMapping]; - if (cellMapping) return [object cellMapping]; - } - - return [self cellMappingForClass:[object class]]; -} - -@end diff --git a/Code/UI/UI.h b/Code/UI/UI.h deleted file mode 100644 index 44ccad27b8..0000000000 --- a/Code/UI/UI.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// UI.h -// RestKit -// -// Created by Blake Watters on 8/8/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. -// - -#ifndef RestKit_UI_h -#define RestKit_UI_h - -#import "RKTableController.h" -#import "RKTableSection.h" -#import "RKTableItem.h" -#import "RKFetchedResultsTableController.h" -#import "RKRefreshTriggerView.h" -#import "RKObjectManager+RKTableController.h" -#import "UIImage+RKAdditions.h" -#import "RKKeyboardScroller.h" - -#endif diff --git a/Code/UI/UIImage+RKAdditions.h b/Code/UI/UIImage+RKAdditions.h deleted file mode 100644 index ee31af3646..0000000000 --- a/Code/UI/UIImage+RKAdditions.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// UIImage+RKAdditions.h -// RestKit -// -// Created by Blake Watters on 2/24/12. -// Copyright (c) 2009-2012 RestKit. All rights reserved. -// - -#if TARGET_OS_IPHONE -#import - -/** - Provides useful extensions to the UIImage interface. - - Resolution indepdence helpers borrowed from: - http://atastypixel.com/blog/uiimage-resolution-independence-and-the-iphone-4s-retina-display/ - */ -@interface UIImage (RKAdditions) - -/** - Creates and returns an image object by loading the image data from the file at the specified path - appropriate for the resolution of the device. - - @param path The full or partial path to the file, possibly including an @2x retina image. - @return A new image object for the specified file, or an image for the @2x version of the specified file, - or nil if the method could not initialize the image from the specified file. - */ -+ (UIImage *)imageWithContentsOfResolutionIndependentFile:(NSString *)path; - -/** - Initializes an image object by loading the image data from the file at the specified path - appropriate for the resolution of the device. - - @param path The full or partial path to the file, possibly including an @2x retina image. - @return The initialized image object for the specified file, or for the @2x version of the specified file, - or nil if the method could not initialize the image from the specified file. - */ -- (id)initWithContentsOfResolutionIndependentFile:(NSString *)path; - -@end - -#endif diff --git a/Code/UI/UIImage+RKAdditions.m b/Code/UI/UIImage+RKAdditions.m deleted file mode 100644 index fe6a8b00e4..0000000000 --- a/Code/UI/UIImage+RKAdditions.m +++ /dev/null @@ -1,38 +0,0 @@ -// -// UIImage+RKAdditions.m -// RestKit -// -// Created by Blake Watters on 2/24/12. -// Copyright (c) 2009-2012 RestKit. All rights reserved. -// - -#import "UIImage+RKAdditions.h" - -#if TARGET_OS_IPHONE - -@implementation UIImage (RKAdditions) - -- (id)initWithContentsOfResolutionIndependentFile:(NSString *)path -{ - if ([[[UIDevice currentDevice] systemVersion] intValue] >= 4 && [[UIScreen mainScreen] scale] == 2.0) { - NSString *path2x = [[path stringByDeletingLastPathComponent] - stringByAppendingPathComponent:[NSString stringWithFormat:@"%@@2x.%@", - [[path lastPathComponent] stringByDeletingPathExtension], - [path pathExtension]]]; - - if ([[NSFileManager defaultManager] fileExistsAtPath:path2x]) { - return [self initWithCGImage:[[UIImage imageWithData:[NSData dataWithContentsOfFile:path2x]] CGImage] scale:2.0 orientation:UIImageOrientationUp]; - } - } - - return [self initWithData:[NSData dataWithContentsOfFile:path]]; -} - -+ (UIImage *)imageWithContentsOfResolutionIndependentFile:(NSString *)path -{ - return [[[UIImage alloc] initWithContentsOfResolutionIndependentFile:path] autorelease]; -} - -@end - -#endif diff --git a/Code/UI/UIView+FindFirstResponder.h b/Code/UI/UIView+FindFirstResponder.h deleted file mode 100644 index 882847abc4..0000000000 --- a/Code/UI/UIView+FindFirstResponder.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// UIView+FindFirstResponder.h -// RestKit -// -// Created by Blake Watters on 8/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 - -@interface UIView (FindFirstResponder) - -- (UIView *)findFirstResponder; - -@end diff --git a/Code/UI/UIView+FindFirstResponder.m b/Code/UI/UIView+FindFirstResponder.m deleted file mode 100644 index c76aa2a00c..0000000000 --- a/Code/UI/UIView+FindFirstResponder.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// UIView+FindFirstResponder.m -// RestKit -// -// Created by Blake Watters on 8/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 "UIView+FindFirstResponder.h" - - -@implementation UIView (FindFirstResponder) - -- (UIView *)findFirstResponder -{ - if (self.isFirstResponder) { - return self; - } - - for (UIView *subView in self.subviews) { - UIView *firstResponder = [subView findFirstResponder]; - if (firstResponder != nil) { - return firstResponder; - } - } - return nil; -} - -@end diff --git a/Resources/RKRefreshTriggerViewAssets/blackArrow.png b/Resources/RKRefreshTriggerViewAssets/blackArrow.png deleted file mode 100644 index 6d2ffbc3a2378449e190e46df4a8f0dde0e2d7ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4316 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 KMNUMnLSTZJBqFB( diff --git a/Resources/RKRefreshTriggerViewAssets/blackArrow@2x.png b/Resources/RKRefreshTriggerViewAssets/blackArrow@2x.png deleted file mode 100644 index ec4ec0e0077ba610b5b3c3b5dee8f661f30a895f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1616 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 diff --git a/Resources/RKRefreshTriggerViewAssets/grayArrow.png b/Resources/RKRefreshTriggerViewAssets/grayArrow.png deleted file mode 100644 index d69e9d94e6ca8f7d1a55087ec45a13b8f66e2e1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1914 zcmaJ?c~BEq91e%nDrh{Q1yfi8RIQRt!V$6>Fc(S0APG?dc*X2OQb;ytH%$OLTFXEz zAjJz>wP>)ZG6?P93AHL(1gB`Jw|Idgga)CMLamnC4HfMlr8~3x-tW!#eZTX~ZcR!Q z`Ai9zLL!lTBw~S_Sl=Sv#gn~=ZwWVe1+nZbu^U=L$l}%1e*|xvlvwBECdJEBbiz~hdR)Bh6-q54mBl8 zN|ze=h(;^UH6qEmi3)XYmYNMy<6?ou7KjkgA-D>#=(6<~WZ_W9bRlBzItHo07zEGa zQ2z-^DNO?Ss1X68X!LM3J(>y zHQ-uQ54aRn>roTVp%Rh)lY-9hN>-1(EE7>M(4sPc3>w{)(l}5m{eP%V_X>^Sa^!Wq z|0#?qatsJ4M=;c6R1=NM2ywYGKzt*j!cn6FMYG4Nn502*6w{yvfS()%NL6aB-er&B zrBXDxpBrYGEiQDms!O6ta0-HlM)|#PfK3E}O*@M)PALqgc`0ajpPW zn{7lJ>TL ztvgxA1XQknxXj z_ElDzYinxuo-eS!J?Fh?)27jOm6wYmi}<(Ptd~e-O<&s%)Yo4vO?lFFcFlCv4DvU9 zp<6;?t)JFTlKFP-@;_Bwy^*{^q4?9?!|U3{N*TrhmVUv-e+_>BqnqH_?Nc6wGD)_~ z&5lLW1#h{@e7^l+owD82>UWYVy5QO5NuCiu;z=IdHL3TKwYnm3X>m)~l7l@n>#D2M zLh>DMGA7!#LsE4;qi9UBVOrhVEn%~~t;;rRW|IGiDyplkZ6LM#9=)oJ-LNqxmDKJH z3g%BmFjXwy9;4WVeS(S_L$0)8)?4GQp|KCt zcm(WeaAQE_aN3sZkBw~T^P({Qmy4sFot^0&9Ua_;HEwt8r%!V>Wo0=deMW*7G~DY4OG-*k$O2a%F9-;7 zugJIC?Qd$b1ADQjE0!#+O9}+_-Ybt>I=XXvC}+UoQ0@<42ODE3O%8`+^}*x$l9>@O zuQ)wDeXS@y-o7*;;dcIwYuECBb~@4ZJ%`Q0c=mYB78a)MKkr_aoROcR^gDJ6F={Y_ll(_8WpT9{Nwl_9*ln>+FF5H-sa&v0ru^c>h!Dz-CnmH{R%HyOL z&%M9&|_?`{fl9=hFx7 Z-Xv1A_~@TKbvD=EP$Ene)biGC`5WGV{&@fZ diff --git a/Resources/RKRefreshTriggerViewAssets/grayArrow@2x.png b/Resources/RKRefreshTriggerViewAssets/grayArrow@2x.png deleted file mode 100644 index 9d42357cf606c2ca4eaf774eb8f27f6c08f36dbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2109 zcmV-D2*US?P)4Tx0C)j~RL^S@K@|QrZmG~B2wH0nvUrdpNm;9CMbtL^5n^i$+aIn^?(HA4aZWV5ov6ELTdbo0FI&wK{O>*+w4vx20?>!`FrQsdJlnHR>OPy zcd~b_n$otK2Za4V;76L-DzNVtaSB-y0*E}{p()372;bw_^6ZZ}PI-92wGS&j#91PI zKs7DSe@(bk%_Y-7gGe}(^>I=@oY#w#*Bu9GZf3^F5WP>3rn}7Ut74&?PWBFvy`A)a zPP5)V!Xd&78LdA?xQ(9mjMYElVd13a#D+Z_7&Y|xU=_C-srWU*6kiZcC!$nw*)9$7 zn6CX+@=AhmkT}X@VSsa5NKe;HZuq)~1$`#h6R+ZTR#D-3j}vF!)ZOnz+5)dI4jl{{ z44Mr{P!L4~VVJN`K!!XTF*LGrKO?IK8z<8w`3e3jI8lUGNUta*C8 zn(P`s>{pjD=7Kek#B;Fw@hxAK%$F&Q6vg9J^Xf~4by_hu-=A!MJ3Znq&n~srbFGPs zH&&aMXZ>nO`|hf|ljc?VPhR!${AbO?W8x_>CU%PFA&Hm8F7cAsOREdwU~R_;ot1_u z(ruCYB-LPGn!NQdT|ZlRy+(fw^-+`=%+gee_kY4FWHg<*4sZI8+sFJD270UUORdLHO0nA4V) z%{fwsET5CQ>B?eK%uw4yQc~9?*JVo2}ze(;aRcp*ceL#HUJSllrgm5wQKR zQu+C;QrUh^8rFfA`ftFz{YAidi-`aL010qNS#tmY3ljhU3ljkVnw%H_00i|(L_t(| z0qtDPOH@%5pEon52GKanXj{v+(Na)x5kU)A{S_5$q>xI8S`>m1Qk$Sf6hur3pu^a33*@N71l3yeE?7X#nj-AyO()H0sW=ewd3 ziBl!DjPLL7r!&Vr&vU>{%BklTStj&p*mgx})4=UkhdQJg*|=0OqEExvF|I+Hk%@Sb zH8?nU%_w4o@xsEw=ZGeySPVS1YZY`~+*u`MhC(q2tZl?Lh8UIRVh}D>lsxiS>&ObeB7$GD0Wn=;3^O?Fkj z#WUyd@bEX4BU9Pj+}st34>52YdUi#6iGhQabON`r$daT;petrPwW$Ke)0rx%WjwWm z6TrP-fOPWic0lcBzbh()PNyAk9o9^29OEYJ>DW5Pbyzd85w8xh1NvzaFv=D?po>v$ zD!EG)6)QGnj&Ymps(d@fRjk;QImT_WtMYxg1HxCUM{>DbL8Z_t!)EzWt1OAnI6b(} z_0!YSQ)2`9_Bc{bY4b)_uL>I)Z0d8j8pvP;Oy<~oj`B?bP!Z* z=z6_A5&Ug)6FBIv0{CtG)M7n!Kmnk?ATvG&p_{--fQBCcJ{2@}%N>|@faP8o&k^9% zP%IXwq4+(l)ahsZ)$UV}x)H{qJP^W~`#h9N_&FC=?!+^Zi0^CNY>j=4aZm!`ij#H6o%C}-z>(- z$>QST8YTkUCGr&qG~raX6OEk-W}F;Ti3DR>B@%WU)oS%| z9Kfh{BjDtewo~;?eI_bElpJqqoCbPSdz{=DI0e|N?$MdZdR(xeojQsXsRW;O?uh{R znY)A6Pg8c>we2-Lt@H{zP6RkP^y~0+*tzPN#ssGIZB?5@mKbmfiYc2)BrSuZt_tm} zq8cUgM1j+kjXffr&8X_~Hrk9+B}`4`7|n zBZKQJ#z3NHlU9KHXzApMjybBeTJ6XwRL~ofyU~;%7Z@AutI)ZG6p7re$N7kC2O}Aq nKcl0gIUD}1G9JlR0uBEGbqpSZw$J)B00000NkvXXu0mjff(!tk diff --git a/Resources/RKRefreshTriggerViewAssets/whiteArrow.png b/Resources/RKRefreshTriggerViewAssets/whiteArrow.png deleted file mode 100644 index 4bf569025ce2b581f13990e6587ec425c44c5448..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4180 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 TeQ@gTe~DWM4fLU>e0 diff --git a/RestKit.xcodeproj/project.pbxproj b/RestKit.xcodeproj/project.pbxproj index 9dedc4ea06..8c22fe7b33 100644 --- a/RestKit.xcodeproj/project.pbxproj +++ b/RestKit.xcodeproj/project.pbxproj @@ -541,8 +541,6 @@ 258EA4AF15A38E7E007E07A6 /* RKMappingOperationDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 258EA4AD15A38E7D007E07A6 /* RKMappingOperationDataSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; 258EA4B215A39090007E07A6 /* RKManagedObjectMappingOperationDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 258EA4B015A3908F007E07A6 /* RKManagedObjectMappingOperationDataSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; 258EA4B315A39090007E07A6 /* RKManagedObjectMappingOperationDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 258EA4B015A3908F007E07A6 /* RKManagedObjectMappingOperationDataSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 258EA57815A63D07007E07A6 /* RKKeyboardScroller.h in Headers */ = {isa = PBXBuildFile; fileRef = 258EA57615A63D07007E07A6 /* RKKeyboardScroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 258EA57A15A63D07007E07A6 /* RKKeyboardScroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 258EA57715A63D07007E07A6 /* RKKeyboardScroller.m */; }; 258EFF7A15C0CE1400EE4E0D /* RKManagedObjectSeederTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 258EFF7915C0CE1400EE4E0D /* RKManagedObjectSeederTest.m */; }; 258EFF7B15C0CE1400EE4E0D /* RKManagedObjectSeederTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 258EFF7915C0CE1400EE4E0D /* RKManagedObjectSeederTest.m */; }; 2597F99C15AF6DC400E547D7 /* RKRelationshipConnectionOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 2597F99A15AF6DC400E547D7 /* RKRelationshipConnectionOperation.h */; }; @@ -605,24 +603,6 @@ 25B408271491CDDC00F21111 /* RKDirectoryUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B408241491CDDB00F21111 /* RKDirectoryUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25B408281491CDDC00F21111 /* RKDirectoryUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B408251491CDDB00F21111 /* RKDirectoryUtilities.m */; }; 25B408291491CDDC00F21111 /* RKDirectoryUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B408251491CDDB00F21111 /* RKDirectoryUtilities.m */; }; - 25B6E91E14CF778D00B1E881 /* RKAbstractTableController.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E90314CF778D00B1E881 /* RKAbstractTableController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25B6E92014CF778D00B1E881 /* RKAbstractTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E90414CF778D00B1E881 /* RKAbstractTableController.m */; }; - 25B6E92314CF778D00B1E881 /* RKAbstractTableController_Internals.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E90614CF778D00B1E881 /* RKAbstractTableController_Internals.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25B6E92D14CF778D00B1E881 /* RKFetchedResultsTableController.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E90B14CF778D00B1E881 /* RKFetchedResultsTableController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25B6E92F14CF778D00B1E881 /* RKFetchedResultsTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E90C14CF778D00B1E881 /* RKFetchedResultsTableController.m */; }; - 25B6E93914CF778D00B1E881 /* RKTableController.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91114CF778D00B1E881 /* RKTableController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25B6E93B14CF778D00B1E881 /* RKTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91214CF778D00B1E881 /* RKTableController.m */; }; - 25B6E93D14CF778D00B1E881 /* RKTableItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91314CF778D00B1E881 /* RKTableItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25B6E93F14CF778D00B1E881 /* RKTableItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91414CF778D00B1E881 /* RKTableItem.m */; }; - 25B6E94114CF778D00B1E881 /* RKTableSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91514CF778D00B1E881 /* RKTableSection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25B6E94314CF778D00B1E881 /* RKTableSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91614CF778D00B1E881 /* RKTableSection.m */; }; - 25B6E94514CF778D00B1E881 /* RKTableViewCellMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91714CF778D00B1E881 /* RKTableViewCellMapping.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25B6E94714CF778D00B1E881 /* RKTableViewCellMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91814CF778D00B1E881 /* RKTableViewCellMapping.m */; }; - 25B6E94914CF778D00B1E881 /* RKTableViewCellMappings.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91914CF778D00B1E881 /* RKTableViewCellMappings.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25B6E94B14CF778D00B1E881 /* RKTableViewCellMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91A14CF778D00B1E881 /* RKTableViewCellMappings.m */; }; - 25B6E94D14CF778D00B1E881 /* UI.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91B14CF778D00B1E881 /* UI.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25B6E94F14CF778D00B1E881 /* UIView+FindFirstResponder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91C14CF778D00B1E881 /* UIView+FindFirstResponder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25B6E95114CF778D00B1E881 /* UIView+FindFirstResponder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91D14CF778D00B1E881 /* UIView+FindFirstResponder.m */; }; 25B6E95514CF795D00B1E881 /* RKErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E95414CF795D00B1E881 /* RKErrors.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25B6E95614CF795D00B1E881 /* RKErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E95414CF795D00B1E881 /* RKErrors.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25B6E95814CF7A1C00B1E881 /* RKErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E95714CF7A1C00B1E881 /* RKErrors.m */; }; @@ -695,7 +675,6 @@ 25B6EA0814CF947E00B1E881 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25B6EA0714CF947D00B1E881 /* CoreGraphics.framework */; }; 25C246A415C83B090032212E /* RKSearchTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25C246A315C83B090032212E /* RKSearchTest.m */; }; 25C246A515C83B090032212E /* RKSearchTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25C246A315C83B090032212E /* RKSearchTest.m */; }; - 25C93DF2157FB6370089259B /* RKTableCellBlockTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 25C93DF1157FB6370089259B /* RKTableCellBlockTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25C954A715542A47005C9E08 /* RKTestConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 25C954A415542A47005C9E08 /* RKTestConstants.m */; }; 25C954A815542A47005C9E08 /* RKTestConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 25C954A415542A47005C9E08 /* RKTestConstants.m */; }; 25CA7A8F14EC570200888FF8 /* RKMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25CA7A8E14EC570100888FF8 /* RKMapping.m */; }; @@ -707,14 +686,8 @@ 25DB7509151BD551009F01AF /* NSManagedObjectContext+RKAdditionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25DB7507151BD551009F01AF /* NSManagedObjectContext+RKAdditionsTest.m */; }; 25E36E0215195CED00F9E448 /* RKFetchRequestMappingCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E36E0115195CED00F9E448 /* RKFetchRequestMappingCacheTest.m */; }; 25E36E0315195CED00F9E448 /* RKFetchRequestMappingCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E36E0115195CED00F9E448 /* RKFetchRequestMappingCacheTest.m */; }; - 25E4DAB4156DA97F00A5C84B /* RKTableControllerTestDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 25E4DAB2156DA97F00A5C84B /* RKTableControllerTestDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25E4DAB5156DA97F00A5C84B /* RKTableControllerTestDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 25E4DAB2156DA97F00A5C84B /* RKTableControllerTestDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25E4DAB6156DA97F00A5C84B /* RKTableControllerTestDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E4DAB3156DA97F00A5C84B /* RKTableControllerTestDelegate.m */; }; 25E4DAB7156DA97F00A5C84B /* RKTableControllerTestDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E4DAB3156DA97F00A5C84B /* RKTableControllerTestDelegate.m */; }; - 25EC1A2C14F6FDAD00C3CF3F /* RKObjectManager+RKTableController.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1A2A14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25EC1A2D14F6FDAD00C3CF3F /* RKObjectManager+RKTableController.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1A2A14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25EC1A2E14F6FDAD00C3CF3F /* RKObjectManager+RKTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1A2B14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.m */; }; - 25EC1A2F14F6FDAD00C3CF3F /* RKObjectManager+RKTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1A2B14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.m */; }; 25EC1A3914F72B0900C3CF3F /* RKFetchRequestManagedObjectCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 7394DF3814CF168C00CE7BCE /* RKFetchRequestManagedObjectCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25EC1A3A14F72B0A00C3CF3F /* RKFetchRequestManagedObjectCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 7394DF3814CF168C00CE7BCE /* RKFetchRequestManagedObjectCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25EC1A3B14F72B1300C3CF3F /* RKFetchRequestManagedObjectCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 7394DF3914CF168C00CE7BCE /* RKFetchRequestManagedObjectCache.m */; }; @@ -729,14 +702,6 @@ 25EC1A4814F7394200C3CF3F /* RKObjectMappingProviderContextEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 73DA8E2014D1C3870054DD73 /* RKObjectMappingProviderContextEntry.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25EC1A6314F7402A00C3CF3F /* RKManagedObjectCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 7394DF3514CF157A00CE7BCE /* RKManagedObjectCaching.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25EC1A6514F7402A00C3CF3F /* RKManagedObjectCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 7394DF3514CF157A00CE7BCE /* RKManagedObjectCaching.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25EC1ABC14F8019F00C3CF3F /* RKRefreshGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1AB814F8019F00C3CF3F /* RKRefreshGestureRecognizer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25EC1ABE14F8019F00C3CF3F /* RKRefreshGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1AB914F8019F00C3CF3F /* RKRefreshGestureRecognizer.m */; }; - 25EC1AC014F8019F00C3CF3F /* RKRefreshTriggerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1ABA14F8019F00C3CF3F /* RKRefreshTriggerView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25EC1AC214F8019F00C3CF3F /* RKRefreshTriggerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1ABB14F8019F00C3CF3F /* RKRefreshTriggerView.m */; }; - 25EC1B3914F84B5D00C3CF3F /* UIImage+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1B3714F84B5C00C3CF3F /* UIImage+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25EC1B3A14F84B5D00C3CF3F /* UIImage+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1B3714F84B5C00C3CF3F /* UIImage+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 25EC1B3B14F84B5D00C3CF3F /* UIImage+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1B3814F84B5C00C3CF3F /* UIImage+RKAdditions.m */; }; - 25EC1B3C14F84B5D00C3CF3F /* UIImage+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1B3814F84B5C00C3CF3F /* UIImage+RKAdditions.m */; }; 25F53ADC15E7B150008B54E6 /* RKRequestDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 25F53ADA15E7B150008B54E6 /* RKRequestDescriptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25F53ADD15E7B150008B54E6 /* RKRequestDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 25F53ADA15E7B150008B54E6 /* RKRequestDescriptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25F53ADE15E7B150008B54E6 /* RKRequestDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 25F53ADB15E7B150008B54E6 /* RKRequestDescriptor.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; @@ -1122,8 +1087,6 @@ 258EA4A715A38BBF007E07A6 /* RKObjectMappingOperationDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMappingOperationDataSource.m; sourceTree = ""; }; 258EA4AD15A38E7D007E07A6 /* RKMappingOperationDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKMappingOperationDataSource.h; sourceTree = ""; }; 258EA4B015A3908F007E07A6 /* RKManagedObjectMappingOperationDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKManagedObjectMappingOperationDataSource.h; sourceTree = ""; }; - 258EA57615A63D07007E07A6 /* RKKeyboardScroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKKeyboardScroller.h; sourceTree = ""; }; - 258EA57715A63D07007E07A6 /* RKKeyboardScroller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKKeyboardScroller.m; sourceTree = ""; }; 258EFF7915C0CE1400EE4E0D /* RKManagedObjectSeederTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectSeederTest.m; sourceTree = ""; }; 2597F99A15AF6DC400E547D7 /* RKRelationshipConnectionOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRelationshipConnectionOperation.h; sourceTree = ""; }; 2597F99B15AF6DC400E547D7 /* RKRelationshipConnectionOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRelationshipConnectionOperation.m; sourceTree = ""; }; @@ -1159,24 +1122,6 @@ 25AFF8F015B4CF1F0051877F /* RKMappingErrors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKMappingErrors.h; sourceTree = ""; }; 25B408241491CDDB00F21111 /* RKDirectoryUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKDirectoryUtilities.h; sourceTree = ""; }; 25B408251491CDDB00F21111 /* RKDirectoryUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKDirectoryUtilities.m; sourceTree = ""; }; - 25B6E90314CF778D00B1E881 /* RKAbstractTableController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKAbstractTableController.h; sourceTree = ""; }; - 25B6E90414CF778D00B1E881 /* RKAbstractTableController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKAbstractTableController.m; sourceTree = ""; }; - 25B6E90614CF778D00B1E881 /* RKAbstractTableController_Internals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKAbstractTableController_Internals.h; sourceTree = ""; }; - 25B6E90B14CF778D00B1E881 /* RKFetchedResultsTableController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKFetchedResultsTableController.h; sourceTree = ""; }; - 25B6E90C14CF778D00B1E881 /* RKFetchedResultsTableController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKFetchedResultsTableController.m; sourceTree = ""; }; - 25B6E91114CF778D00B1E881 /* RKTableController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTableController.h; sourceTree = ""; }; - 25B6E91214CF778D00B1E881 /* RKTableController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTableController.m; sourceTree = ""; }; - 25B6E91314CF778D00B1E881 /* RKTableItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTableItem.h; sourceTree = ""; }; - 25B6E91414CF778D00B1E881 /* RKTableItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTableItem.m; sourceTree = ""; }; - 25B6E91514CF778D00B1E881 /* RKTableSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTableSection.h; sourceTree = ""; }; - 25B6E91614CF778D00B1E881 /* RKTableSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTableSection.m; sourceTree = ""; }; - 25B6E91714CF778D00B1E881 /* RKTableViewCellMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTableViewCellMapping.h; sourceTree = ""; }; - 25B6E91814CF778D00B1E881 /* RKTableViewCellMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTableViewCellMapping.m; sourceTree = ""; }; - 25B6E91914CF778D00B1E881 /* RKTableViewCellMappings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTableViewCellMappings.h; sourceTree = ""; }; - 25B6E91A14CF778D00B1E881 /* RKTableViewCellMappings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTableViewCellMappings.m; sourceTree = ""; }; - 25B6E91B14CF778D00B1E881 /* UI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UI.h; sourceTree = ""; }; - 25B6E91C14CF778D00B1E881 /* UIView+FindFirstResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+FindFirstResponder.h"; sourceTree = ""; }; - 25B6E91D14CF778D00B1E881 /* UIView+FindFirstResponder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+FindFirstResponder.m"; sourceTree = ""; }; 25B6E95414CF795D00B1E881 /* RKErrors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKErrors.h; sourceTree = ""; }; 25B6E95714CF7A1C00B1E881 /* RKErrors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKErrors.m; sourceTree = ""; }; 25B6E95A14CF7E3C00B1E881 /* RKDynamicMappingMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKDynamicMappingMatcher.h; sourceTree = ""; }; @@ -1234,7 +1179,6 @@ 25B6EA0514CF946300B1E881 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 25B6EA0714CF947D00B1E881 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 25C246A315C83B090032212E /* RKSearchTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKSearchTest.m; sourceTree = ""; }; - 25C93DF1157FB6370089259B /* RKTableCellBlockTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTableCellBlockTypes.h; sourceTree = ""; }; 25C954A415542A47005C9E08 /* RKTestConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKTestConstants.m; path = Testing/RKTestConstants.m; sourceTree = ""; }; 25CA7A8E14EC570100888FF8 /* RKMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKMapping.m; sourceTree = ""; }; 25CAAA9315254E7800CAE5D7 /* ArrayOfHumans.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ArrayOfHumans.json; sourceTree = ""; }; @@ -1242,12 +1186,6 @@ 25E36E0115195CED00F9E448 /* RKFetchRequestMappingCacheTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKFetchRequestMappingCacheTest.m; sourceTree = ""; }; 25E4DAB2156DA97F00A5C84B /* RKTableControllerTestDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKTableControllerTestDelegate.h; path = Testing/RKTableControllerTestDelegate.h; sourceTree = ""; }; 25E4DAB3156DA97F00A5C84B /* RKTableControllerTestDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKTableControllerTestDelegate.m; path = Testing/RKTableControllerTestDelegate.m; sourceTree = ""; }; - 25EC1A2A14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RKObjectManager+RKTableController.h"; sourceTree = ""; }; - 25EC1A2B14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RKObjectManager+RKTableController.m"; sourceTree = ""; }; - 25EC1AB814F8019F00C3CF3F /* RKRefreshGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRefreshGestureRecognizer.h; sourceTree = ""; }; - 25EC1AB914F8019F00C3CF3F /* RKRefreshGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRefreshGestureRecognizer.m; sourceTree = ""; }; - 25EC1ABA14F8019F00C3CF3F /* RKRefreshTriggerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRefreshTriggerView.h; sourceTree = ""; }; - 25EC1ABB14F8019F00C3CF3F /* RKRefreshTriggerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRefreshTriggerView.m; sourceTree = ""; }; 25EC1AD814F8022600C3CF3F /* RestKitFramework-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RestKitFramework-Info.plist"; sourceTree = ""; }; 25EC1AD914F8022600C3CF3F /* RestKitFrameworkTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RestKitFrameworkTests-Info.plist"; sourceTree = ""; }; 25EC1ADA14F8022600C3CF3F /* RestKitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RestKitTests-Info.plist"; sourceTree = ""; }; @@ -1262,8 +1200,6 @@ 25EC1B0014F8078100C3CF3F /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 25EC1B1E14F821B500C3CF3F /* RestKitResources-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RestKitResources-Prefix.pch"; sourceTree = ""; }; 25EC1B1F14F8220800C3CF3F /* RestKitResources-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RestKitResources-Info.plist"; sourceTree = ""; }; - 25EC1B3714F84B5C00C3CF3F /* UIImage+RKAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+RKAdditions.h"; sourceTree = ""; }; - 25EC1B3814F84B5C00C3CF3F /* UIImage+RKAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+RKAdditions.m"; sourceTree = ""; }; 25F53ADA15E7B150008B54E6 /* RKRequestDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRequestDescriptor.h; sourceTree = ""; }; 25F53ADB15E7B150008B54E6 /* RKRequestDescriptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequestDescriptor.m; sourceTree = ""; }; 25F53AE015E7B611008B54E6 /* RKHTTPUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKHTTPUtilities.h; sourceTree = ""; }; @@ -1459,7 +1395,6 @@ 25160D7A145650490060A5C5 /* ObjectMapping */, 25160D45145650490060A5C5 /* CoreData */, 25160DA2145650490060A5C5 /* Support */, - 25B6E90214CF778D00B1E881 /* UI */, 252EFB1F14D9A8D4004863C8 /* Testing */, 25104F0E15C30C7900829135 /* Search */, ); @@ -2096,42 +2031,6 @@ name = Testing; sourceTree = ""; }; - 25B6E90214CF778D00B1E881 /* UI */ = { - isa = PBXGroup; - children = ( - 25EC1AB814F8019F00C3CF3F /* RKRefreshGestureRecognizer.h */, - 25EC1AB914F8019F00C3CF3F /* RKRefreshGestureRecognizer.m */, - 25EC1ABA14F8019F00C3CF3F /* RKRefreshTriggerView.h */, - 25EC1ABB14F8019F00C3CF3F /* RKRefreshTriggerView.m */, - 25B6E90314CF778D00B1E881 /* RKAbstractTableController.h */, - 25B6E90414CF778D00B1E881 /* RKAbstractTableController.m */, - 25B6E90614CF778D00B1E881 /* RKAbstractTableController_Internals.h */, - 25B6E90B14CF778D00B1E881 /* RKFetchedResultsTableController.h */, - 25B6E90C14CF778D00B1E881 /* RKFetchedResultsTableController.m */, - 25B6E91114CF778D00B1E881 /* RKTableController.h */, - 25B6E91214CF778D00B1E881 /* RKTableController.m */, - 25B6E91314CF778D00B1E881 /* RKTableItem.h */, - 25B6E91414CF778D00B1E881 /* RKTableItem.m */, - 25B6E91514CF778D00B1E881 /* RKTableSection.h */, - 25B6E91614CF778D00B1E881 /* RKTableSection.m */, - 25B6E91714CF778D00B1E881 /* RKTableViewCellMapping.h */, - 25B6E91814CF778D00B1E881 /* RKTableViewCellMapping.m */, - 25B6E91914CF778D00B1E881 /* RKTableViewCellMappings.h */, - 25B6E91A14CF778D00B1E881 /* RKTableViewCellMappings.m */, - 25B6E91B14CF778D00B1E881 /* UI.h */, - 25B6E91C14CF778D00B1E881 /* UIView+FindFirstResponder.h */, - 25B6E91D14CF778D00B1E881 /* UIView+FindFirstResponder.m */, - 25EC1A2A14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.h */, - 25EC1A2B14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.m */, - 25EC1B3714F84B5C00C3CF3F /* UIImage+RKAdditions.h */, - 25EC1B3814F84B5C00C3CF3F /* UIImage+RKAdditions.m */, - 25C93DF1157FB6370089259B /* RKTableCellBlockTypes.h */, - 258EA57615A63D07007E07A6 /* RKKeyboardScroller.h */, - 258EA57715A63D07007E07A6 /* RKKeyboardScroller.m */, - ); - path = UI; - sourceTree = ""; - }; 25B6E97A14CF829400B1E881 /* OCMock */ = { isa = PBXGroup; children = ( @@ -2354,14 +2253,9 @@ 25055B8414EEF32A00B9C4DD /* RKMappingTest.h in Headers */, 25055B8814EEF32A00B9C4DD /* RKTestFactory.h in Headers */, 25055B8F14EEF40000B9C4DD /* RKMappingTestExpectation.h in Headers */, - 25EC1A2C14F6FDAD00C3CF3F /* RKObjectManager+RKTableController.h in Headers */, 25EC1A3914F72B0900C3CF3F /* RKFetchRequestManagedObjectCache.h in Headers */, 25EC1A3D14F72B2800C3CF3F /* RKInMemoryManagedObjectCache.h in Headers */, - 25EC1A4714F7394100C3CF3F /* RKObjectMappingProviderContextEntry.h in Headers */, 25EC1A6314F7402A00C3CF3F /* RKManagedObjectCaching.h in Headers */, - 25EC1ABC14F8019F00C3CF3F /* RKRefreshGestureRecognizer.h in Headers */, - 25EC1AC014F8019F00C3CF3F /* RKRefreshTriggerView.h in Headers */, - 25EC1B3914F84B5D00C3CF3F /* UIImage+RKAdditions.h in Headers */, 257ABAB015112DD500CCAA76 /* NSManagedObjectContext+RKAdditions.h in Headers */, 257ABAB61511371E00CCAA76 /* NSManagedObject+RKAdditions.h in Headers */, 25079C6F151B93DB00266AE7 /* NSEntityDescription+RKAdditions.h in Headers */, @@ -2374,10 +2268,7 @@ 252029031577AE1800076FB4 /* RKRoute.h in Headers */, 258113C815781848009835EB /* RKObjectMappingProvider+CoreData.h in Headers */, 25545959155F0527007D7625 /* RKBenchmark.h in Headers */, - 25E4DAB4156DA97F00A5C84B /* RKTableControllerTestDelegate.h in Headers */, - 25C93DF2157FB6370089259B /* RKTableCellBlockTypes.h in Headers */, 25FBB852159272DD00955D27 /* RKRouter.h in Headers */, - 258EA57815A63D07007E07A6 /* RKKeyboardScroller.h in Headers */, 258EA4A815A38BC0007E07A6 /* RKObjectMappingOperationDataSource.h in Headers */, 258EA4AE15A38E7E007E07A6 /* RKMappingOperationDataSource.h in Headers */, 258EA4B215A39090007E07A6 /* RKManagedObjectMappingOperationDataSource.h in Headers */, @@ -2496,7 +2387,6 @@ 25EC1A3E14F72B2900C3CF3F /* RKInMemoryManagedObjectCache.h in Headers */, 25EC1A4814F7394200C3CF3F /* RKObjectMappingProviderContextEntry.h in Headers */, 25EC1A6514F7402A00C3CF3F /* RKManagedObjectCaching.h in Headers */, - 25EC1B3A14F84B5D00C3CF3F /* UIImage+RKAdditions.h in Headers */, 257ABAB115112DD500CCAA76 /* NSManagedObjectContext+RKAdditions.h in Headers */, 257ABAB71511371E00CCAA76 /* NSManagedObject+RKAdditions.h in Headers */, 25079C70151B93DB00266AE7 /* NSEntityDescription+RKAdditions.h in Headers */, @@ -2885,14 +2775,6 @@ 250DF22C14C5190E0001DEFA /* RKOrderedDictionary.m in Sources */, 49D2759F14C9EF1E0090845D /* ISO8601DateFormatter.m in Sources */, 49D275AF14C9F3020090845D /* RKISO8601DateFormatter.m in Sources */, - 25B6E92014CF778D00B1E881 /* RKAbstractTableController.m in Sources */, - 25B6E92F14CF778D00B1E881 /* RKFetchedResultsTableController.m in Sources */, - 25B6E93B14CF778D00B1E881 /* RKTableController.m in Sources */, - 25B6E93F14CF778D00B1E881 /* RKTableItem.m in Sources */, - 25B6E94314CF778D00B1E881 /* RKTableSection.m in Sources */, - 25B6E94714CF778D00B1E881 /* RKTableViewCellMapping.m in Sources */, - 25B6E94B14CF778D00B1E881 /* RKTableViewCellMappings.m in Sources */, - 25B6E95114CF778D00B1E881 /* UIView+FindFirstResponder.m in Sources */, 25B6E95814CF7A1C00B1E881 /* RKErrors.m in Sources */, 25B6E95E14CF7E3C00B1E881 /* RKDynamicMappingMatcher.m in Sources */, 25B6E9FF14CF943E00B1E881 /* RKCache.m in Sources */, @@ -2910,9 +2792,6 @@ 25EC1A3B14F72B1300C3CF3F /* RKFetchRequestManagedObjectCache.m in Sources */, 25EC1A3F14F72B3100C3CF3F /* RKInMemoryManagedObjectCache.m in Sources */, 25EC1A4514F7393D00C3CF3F /* RKObjectMappingProviderContextEntry.m in Sources */, - 25EC1ABE14F8019F00C3CF3F /* RKRefreshGestureRecognizer.m in Sources */, - 25EC1AC214F8019F00C3CF3F /* RKRefreshTriggerView.m in Sources */, - 25EC1B3B14F84B5D00C3CF3F /* UIImage+RKAdditions.m in Sources */, 257ABAB215112DD500CCAA76 /* NSManagedObjectContext+RKAdditions.m in Sources */, 257ABAB81511371E00CCAA76 /* NSManagedObject+RKAdditions.m in Sources */, 25079C71151B93DB00266AE7 /* NSEntityDescription+RKAdditions.m in Sources */, @@ -2922,13 +2801,11 @@ 259D98561550C69A008C90F5 /* RKEntityByAttributeCache.m in Sources */, 259D9860155218E5008C90F5 /* RKEntityCache.m in Sources */, 2554595B155F0527007D7625 /* RKBenchmark.m in Sources */, - 25E4DAB6156DA97F00A5C84B /* RKTableControllerTestDelegate.m in Sources */, 8BC044CB1576CE72003DCDD6 /* RKConnectionMapping.m in Sources */, 252028FE1577AE0B00076FB4 /* RKRouteSet.m in Sources */, 252029051577AE1800076FB4 /* RKRoute.m in Sources */, 258113CD15781871009835EB /* RKObjectMappingProvider+CoreData.m in Sources */, 25FBB854159272DD00955D27 /* RKRouter.m in Sources */, - 258EA57A15A63D07007E07A6 /* RKKeyboardScroller.m in Sources */, 258EA4AA15A38BC0007E07A6 /* RKObjectMappingOperationDataSource.m in Sources */, 25AA23D015AF2920006EF62D /* RKManagedObjectMappingOperationDataSource.m in Sources */, 2597F99E15AF6DC400E547D7 /* RKRelationshipConnectionOperation.m in Sources */, @@ -3117,7 +2994,6 @@ 25EC1A3C14F72B1400C3CF3F /* RKFetchRequestManagedObjectCache.m in Sources */, 25EC1A4014F72B3300C3CF3F /* RKInMemoryManagedObjectCache.m in Sources */, 25EC1A4614F7393E00C3CF3F /* RKObjectMappingProviderContextEntry.m in Sources */, - 25EC1B3C14F84B5D00C3CF3F /* UIImage+RKAdditions.m in Sources */, 257ABAB315112DD500CCAA76 /* NSManagedObjectContext+RKAdditions.m in Sources */, 257ABAB91511371E00CCAA76 /* NSManagedObject+RKAdditions.m in Sources */, 25079C72151B93DB00266AE7 /* NSEntityDescription+RKAdditions.m in Sources */, diff --git a/RestKitResources.bundle/Contents/Info.plist b/RestKitResources.bundle/Contents/Info.plist deleted file mode 100644 index b7c33a135e..0000000000 --- a/RestKitResources.bundle/Contents/Info.plist +++ /dev/null @@ -1,60 +0,0 @@ - - - - - BuildMachineOSBuild - 11D50b - CFBundleDevelopmentRegion - English - CFBundleExecutable - RestKitResources - CFBundleIdentifier - org.restkit.RestKitResources - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - RestKitResources - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - CFPlugInDynamicRegisterFunction - - CFPlugInDynamicRegistration - NO - CFPlugInFactories - - 00000000-0000-0000-0000-000000000000 - MyFactoryFunction - - CFPlugInTypes - - 00000000-0000-0000-0000-000000000000 - - 00000000-0000-0000-0000-000000000000 - - - CFPlugInUnloadFunction - - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 4E1019 - DTPlatformVersion - GM - DTSDKBuild - 11D50a - DTSDKName - macosx10.7 - DTXcode - 0431 - DTXcodeBuild - 4E1019 - NSHumanReadableCopyright - Copyright © 2012 RestKit. All rights reserved. - - diff --git a/RestKitResources.bundle/Contents/Resources/blackArrow.png b/RestKitResources.bundle/Contents/Resources/blackArrow.png deleted file mode 100644 index 6d2ffbc3a2378449e190e46df4a8f0dde0e2d7ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4316 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 KMNUMnLSTZJBqFB( diff --git a/RestKitResources.bundle/Contents/Resources/blackArrow@2x.png b/RestKitResources.bundle/Contents/Resources/blackArrow@2x.png deleted file mode 100644 index ec4ec0e0077ba610b5b3c3b5dee8f661f30a895f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1616 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 diff --git a/RestKitResources.bundle/Contents/Resources/grayArrow.png b/RestKitResources.bundle/Contents/Resources/grayArrow.png deleted file mode 100644 index d69e9d94e6ca8f7d1a55087ec45a13b8f66e2e1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1914 zcmaJ?c~BEq91e%nDrh{Q1yfi8RIQRt!V$6>Fc(S0APG?dc*X2OQb;ytH%$OLTFXEz zAjJz>wP>)ZG6?P93AHL(1gB`Jw|Idgga)CMLamnC4HfMlr8~3x-tW!#eZTX~ZcR!Q z`Ai9zLL!lTBw~S_Sl=Sv#gn~=ZwWVe1+nZbu^U=L$l}%1e*|xvlvwBECdJEBbiz~hdR)Bh6-q54mBl8 zN|ze=h(;^UH6qEmi3)XYmYNMy<6?ou7KjkgA-D>#=(6<~WZ_W9bRlBzItHo07zEGa zQ2z-^DNO?Ss1X68X!LM3J(>y zHQ-uQ54aRn>roTVp%Rh)lY-9hN>-1(EE7>M(4sPc3>w{)(l}5m{eP%V_X>^Sa^!Wq z|0#?qatsJ4M=;c6R1=NM2ywYGKzt*j!cn6FMYG4Nn502*6w{yvfS()%NL6aB-er&B zrBXDxpBrYGEiQDms!O6ta0-HlM)|#PfK3E}O*@M)PALqgc`0ajpPW zn{7lJ>TL ztvgxA1XQknxXj z_ElDzYinxuo-eS!J?Fh?)27jOm6wYmi}<(Ptd~e-O<&s%)Yo4vO?lFFcFlCv4DvU9 zp<6;?t)JFTlKFP-@;_Bwy^*{^q4?9?!|U3{N*TrhmVUv-e+_>BqnqH_?Nc6wGD)_~ z&5lLW1#h{@e7^l+owD82>UWYVy5QO5NuCiu;z=IdHL3TKwYnm3X>m)~l7l@n>#D2M zLh>DMGA7!#LsE4;qi9UBVOrhVEn%~~t;;rRW|IGiDyplkZ6LM#9=)oJ-LNqxmDKJH z3g%BmFjXwy9;4WVeS(S_L$0)8)?4GQp|KCt zcm(WeaAQE_aN3sZkBw~T^P({Qmy4sFot^0&9Ua_;HEwt8r%!V>Wo0=deMW*7G~DY4OG-*k$O2a%F9-;7 zugJIC?Qd$b1ADQjE0!#+O9}+_-Ybt>I=XXvC}+UoQ0@<42ODE3O%8`+^}*x$l9>@O zuQ)wDeXS@y-o7*;;dcIwYuECBb~@4ZJ%`Q0c=mYB78a)MKkr_aoROcR^gDJ6F={Y_ll(_8WpT9{Nwl_9*ln>+FF5H-sa&v0ru^c>h!Dz-CnmH{R%HyOL z&%M9&|_?`{fl9=hFx7 Z-Xv1A_~@TKbvD=EP$Ene)biGC`5WGV{&@fZ diff --git a/RestKitResources.bundle/Contents/Resources/grayArrow@2x.png b/RestKitResources.bundle/Contents/Resources/grayArrow@2x.png deleted file mode 100644 index 9d42357cf606c2ca4eaf774eb8f27f6c08f36dbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2109 zcmV-D2*US?P)4Tx0C)j~RL^S@K@|QrZmG~B2wH0nvUrdpNm;9CMbtL^5n^i$+aIn^?(HA4aZWV5ov6ELTdbo0FI&wK{O>*+w4vx20?>!`FrQsdJlnHR>OPy zcd~b_n$otK2Za4V;76L-DzNVtaSB-y0*E}{p()372;bw_^6ZZ}PI-92wGS&j#91PI zKs7DSe@(bk%_Y-7gGe}(^>I=@oY#w#*Bu9GZf3^F5WP>3rn}7Ut74&?PWBFvy`A)a zPP5)V!Xd&78LdA?xQ(9mjMYElVd13a#D+Z_7&Y|xU=_C-srWU*6kiZcC!$nw*)9$7 zn6CX+@=AhmkT}X@VSsa5NKe;HZuq)~1$`#h6R+ZTR#D-3j}vF!)ZOnz+5)dI4jl{{ z44Mr{P!L4~VVJN`K!!XTF*LGrKO?IK8z<8w`3e3jI8lUGNUta*C8 zn(P`s>{pjD=7Kek#B;Fw@hxAK%$F&Q6vg9J^Xf~4by_hu-=A!MJ3Znq&n~srbFGPs zH&&aMXZ>nO`|hf|ljc?VPhR!${AbO?W8x_>CU%PFA&Hm8F7cAsOREdwU~R_;ot1_u z(ruCYB-LPGn!NQdT|ZlRy+(fw^-+`=%+gee_kY4FWHg<*4sZI8+sFJD270UUORdLHO0nA4V) z%{fwsET5CQ>B?eK%uw4yQc~9?*JVo2}ze(;aRcp*ceL#HUJSllrgm5wQKR zQu+C;QrUh^8rFfA`ftFz{YAidi-`aL010qNS#tmY3ljhU3ljkVnw%H_00i|(L_t(| z0qtDPOH@%5pEon52GKanXj{v+(Na)x5kU)A{S_5$q>xI8S`>m1Qk$Sf6hur3pu^a33*@N71l3yeE?7X#nj-AyO()H0sW=ewd3 ziBl!DjPLL7r!&Vr&vU>{%BklTStj&p*mgx})4=UkhdQJg*|=0OqEExvF|I+Hk%@Sb zH8?nU%_w4o@xsEw=ZGeySPVS1YZY`~+*u`MhC(q2tZl?Lh8UIRVh}D>lsxiS>&ObeB7$GD0Wn=;3^O?Fkj z#WUyd@bEX4BU9Pj+}st34>52YdUi#6iGhQabON`r$daT;petrPwW$Ke)0rx%WjwWm z6TrP-fOPWic0lcBzbh()PNyAk9o9^29OEYJ>DW5Pbyzd85w8xh1NvzaFv=D?po>v$ zD!EG)6)QGnj&Ymps(d@fRjk;QImT_WtMYxg1HxCUM{>DbL8Z_t!)EzWt1OAnI6b(} z_0!YSQ)2`9_Bc{bY4b)_uL>I)Z0d8j8pvP;Oy<~oj`B?bP!Z* z=z6_A5&Ug)6FBIv0{CtG)M7n!Kmnk?ATvG&p_{--fQBCcJ{2@}%N>|@faP8o&k^9% zP%IXwq4+(l)ahsZ)$UV}x)H{qJP^W~`#h9N_&FC=?!+^Zi0^CNY>j=4aZm!`ij#H6o%C}-z>(- z$>QST8YTkUCGr&qG~raX6OEk-W}F;Ti3DR>B@%WU)oS%| z9Kfh{BjDtewo~;?eI_bElpJqqoCbPSdz{=DI0e|N?$MdZdR(xeojQsXsRW;O?uh{R znY)A6Pg8c>we2-Lt@H{zP6RkP^y~0+*tzPN#ssGIZB?5@mKbmfiYc2)BrSuZt_tm} zq8cUgM1j+kjXffr&8X_~Hrk9+B}`4`7|n zBZKQJ#z3NHlU9KHXzApMjybBeTJ6XwRL~ofyU~;%7Z@AutI)ZG6p7re$N7kC2O}Aq nKcl0gIUD}1G9JlR0uBEGbqpSZw$J)B00000NkvXXu0mjff(!tk diff --git a/RestKitResources.bundle/Contents/Resources/whiteArrow.png b/RestKitResources.bundle/Contents/Resources/whiteArrow.png deleted file mode 100644 index 4bf569025ce2b581f13990e6587ec425c44c5448..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4180 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 TeQ@gTe~DWM4fLU>e0