Permalink
Browse files

Better table view

  • Loading branch information...
1 parent bb0d96d commit 1172eb9cbf1cdec4e8b7f01ca5ade917a639f09b @winfield committed Mar 5, 2012
@@ -15,7 +15,7 @@
F3269D9F150390E100C7D2DA /* RCIAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F3269D9E150390E100C7D2DA /* RCIAppDelegate.m */; };
F3269DA2150390E100C7D2DA /* MainStoryboard_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F3269DA0150390E100C7D2DA /* MainStoryboard_iPhone.storyboard */; };
F3269DA5150390E100C7D2DA /* MainStoryboard_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F3269DA3150390E100C7D2DA /* MainStoryboard_iPad.storyboard */; };
- F3269DA8150390E100C7D2DA /* RCIViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F3269DA7150390E100C7D2DA /* RCIViewController.m */; };
+ F3269DA8150390E100C7D2DA /* RCITopicViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F3269DA7150390E100C7D2DA /* RCITopicViewController.m */; };
F3D546021503A59700F5A9E3 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3D546001503A59700F5A9E3 /* CFNetwork.framework */; };
F3D546031503A59700F5A9E3 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3D546011503A59700F5A9E3 /* CoreData.framework */; };
F3D546051503A5A600F5A9E3 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3D546041503A5A600F5A9E3 /* MobileCoreServices.framework */; };
@@ -79,8 +79,8 @@
F3269D9E150390E100C7D2DA /* RCIAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCIAppDelegate.m; sourceTree = "<group>"; };
F3269DA1150390E100C7D2DA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard_iPhone.storyboard; sourceTree = "<group>"; };
F3269DA4150390E100C7D2DA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard_iPad.storyboard; sourceTree = "<group>"; };
- F3269DA6150390E100C7D2DA /* RCIViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCIViewController.h; sourceTree = "<group>"; };
- F3269DA7150390E100C7D2DA /* RCIViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCIViewController.m; sourceTree = "<group>"; };
+ F3269DA6150390E100C7D2DA /* RCITopicViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCITopicViewController.h; sourceTree = "<group>"; };
+ F3269DA7150390E100C7D2DA /* RCITopicViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCITopicViewController.m; sourceTree = "<group>"; };
F3D545EA1503A44D00F5A9E3 /* RestKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RestKit.xcodeproj; path = ../RestKit/RestKit.xcodeproj; sourceTree = "<group>"; };
F3D546001503A59700F5A9E3 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
F3D546011503A59700F5A9E3 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
@@ -159,8 +159,8 @@
F3269D9E150390E100C7D2DA /* RCIAppDelegate.m */,
F3269DA0150390E100C7D2DA /* MainStoryboard_iPhone.storyboard */,
F3269DA3150390E100C7D2DA /* MainStoryboard_iPad.storyboard */,
- F3269DA6150390E100C7D2DA /* RCIViewController.h */,
- F3269DA7150390E100C7D2DA /* RCIViewController.m */,
+ F3269DA6150390E100C7D2DA /* RCITopicViewController.h */,
+ F3269DA7150390E100C7D2DA /* RCITopicViewController.m */,
F3D5463F1503B7BA00F5A9E3 /* RCITopic.h */,
F3D546401503B7BA00F5A9E3 /* RCITopic.m */,
F3D5464F1503B89E00F5A9E3 /* RCIUser.h */,
@@ -297,7 +297,7 @@
files = (
F3269D9B150390E000C7D2DA /* main.m in Sources */,
F3269D9F150390E100C7D2DA /* RCIAppDelegate.m in Sources */,
- F3269DA8150390E100C7D2DA /* RCIViewController.m in Sources */,
+ F3269DA8150390E100C7D2DA /* RCITopicViewController.m in Sources */,
F3D546411503B7BA00F5A9E3 /* RCITopic.m in Sources */,
F3D546511503B89F00F5A9E3 /* RCIUser.m in Sources */,
);
@@ -29,13 +29,13 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
- (void)initRestKit {
RKObjectManager *manager = [RKObjectManager objectManagerWithBaseURL:API_ENDPOINT];
-//
-// RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:[RCIUser class]];
-// [userMapping mapAttributes:@"login", @"name", @"location", @"bio", @"tagline", @"website", nil];
-// [userMapping mapKeyPathsToAttributes:@"github_url", @"githubUrl",
-// @"gravatar_hash", @"gravatarHash",
-// nil];
-// [manager.mappingProvider addObjectMapping:userMapping];
+
+ RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:[RCIUser class]];
+ [userMapping mapAttributes:@"login", @"name", @"location", @"bio", @"tagline", @"website", nil];
+ [userMapping mapKeyPathsToAttributes:@"github_url", @"githubUrl",
+ @"gravatar_hash", @"gravatarHash",
+ nil];
+ [manager.mappingProvider addObjectMapping:userMapping];
RKObjectMapping *topicMapping = [RKObjectMapping mappingForClass:[RCITopic class]];
[topicMapping mapKeyPathsToAttributes: @"title", @"title",
@@ -44,7 +44,7 @@ - (void)initRestKit {
@"updated_at", @"updatedDate",
@"node_name", @"nodeName",
nil];
-// [topicMapping mapRelationship:@"user" withMapping:userMapping];
+ [topicMapping mapRelationship:@"user" withMapping:userMapping];
[manager.mappingProvider addObjectMapping:topicMapping];
}
@@ -16,6 +16,6 @@
@property (nonatomic, strong) NSDate *createdDate;
@property (nonatomic, strong) NSDate *updatedDate;
@property (nonatomic, strong) NSString *nodeName;
-//@property (nonatomic, strong) RCIUser *user;
+@property (nonatomic, strong) RCIUser *user;
@end
@@ -14,6 +14,6 @@ @implementation RCITopic
@synthesize createdDate = _createdDate;
@synthesize updatedDate = _updatedDate;
@synthesize nodeName = _nodeName;
-//@synthesize user = _user;
+@synthesize user = _user;
@end
@@ -9,6 +9,6 @@
#import <UIKit/UIKit.h>
#import <RestKit/RestKit.h>
-@interface RCIViewController : UITableViewController <RKObjectLoaderDelegate>
+@interface RCITopicViewController : UITableViewController <RKObjectLoaderDelegate>
@end
@@ -6,17 +6,30 @@
// Copyright (c) 2012 lainuo.info. All rights reserved.
//
-#import "RCIViewController.h"
+#import "RCITopicViewController.h"
#import "RCITopic.h"
-@interface RCIViewController ()
+NSString *const RCITopicPropertyNamedGravatar = @"user.gravatar";
+
+@interface RCITopicViewController ()
@property (nonatomic, strong) NSArray *topics;
@property (nonatomic, weak) IBOutlet UITableView* topicTableView;
+@property (nonatomic, strong) NSMutableArray *observedVisibleItems;
@end
-@implementation RCIViewController
+@implementation RCITopicViewController
@synthesize topicTableView = _topicTableView;
@synthesize topics = _topics;
+@synthesize observedVisibleItems = _observedVisibleItems;
+
+- (NSMutableArray *)observedVisibleItems
+{
+ if (!_observedVisibleItems) {
+ _observedVisibleItems = [[NSMutableArray alloc] init];
+ }
+
+ return _observedVisibleItems;
+}
- (void)viewDidLoad
{
@@ -65,7 +78,30 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
RCITopic *topic = [self.topics objectAtIndex:indexPath.row];
- cell.textLabel.text = topic.title;
+
+ UILabel *titleLabel = (UILabel *)[cell viewWithTag:101];
+ titleLabel.text = topic.title;
+ UILabel *userLabel = (UILabel *)[cell viewWithTag:102];
+ userLabel.text = topic.user.login;
+ UILabel *nodeLabel = (UILabel *)[cell viewWithTag:103];
+ nodeLabel.text = topic.nodeName;
+ UILabel *countLabel = (UILabel *)[cell viewWithTag:104];
+ countLabel.text = topic.repliesCount.stringValue;
+ // cell.textLabel.text = topic.title;
+
+ if (![self.observedVisibleItems containsObject:topic.user]) {
+ [topic addObserver:self forKeyPath:RCITopicPropertyNamedGravatar options:0 context:NULL];
+ [topic.user loadGravatar];
+ [self.observedVisibleItems addObject:topic.user];
+ }
+
+ UIActivityIndicatorView *progressIndicator = (UIActivityIndicatorView *)[cell viewWithTag:105];
+ UIImageView *imageView = (UIImageView *)[cell viewWithTag:106];
+ if (topic.user.gravatar == nil) {
+ [progressIndicator setHidden:NO];
+ } else {
+ imageView.image = topic.user.gravatar;
+ }
return cell;
}
@@ -85,6 +121,21 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
+ if ([keyPath isEqualToString:RCITopicPropertyNamedGravatar]) {
+ [self performSelectorOnMainThread:@selector(reloadRowForEntity:) withObject:object waitUntilDone:NO modes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
+ }
+}
+
+- (void)reloadRowForEntity:(id)object {
+ NSInteger row = [self.topics indexOfObject:object];
+ if (row != NSNotFound) {
+ RCITopic *topic = [self.topics objectAtIndex:row];
+ UITableViewCell *cell = [self.topicTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0]];
+ UIImageView *imageView = (UIImageView *)[cell viewWithTag:106];
+ imageView.image = topic.user.gravatar;
+ UIActivityIndicatorView *progressIndicator = (UIActivityIndicatorView *)[cell viewWithTag:105];
+ [progressIndicator setHidden:YES];
+ }
}
@end
View
@@ -10,4 +10,18 @@
@interface RCIUser : NSObject
+@property (nonatomic, strong) NSString *login;
+@property (nonatomic, strong) NSString *name;
+@property (nonatomic, strong) NSString *location;
+@property (nonatomic, strong) NSString *bio;
+@property (nonatomic, strong) NSString *tagline;
+@property (nonatomic, strong) NSString *website;
+@property (nonatomic, strong) NSString *githubUrl;
+@property (nonatomic, strong) NSString *gravatarHash;
+
+@property (assign) BOOL loadingGravatar;
+@property (nonatomic, strong) UIImage *gravatar;
+
+- (void)loadGravatar;
+
@end
View
@@ -10,4 +10,50 @@
@implementation RCIUser
+@synthesize login = _login;
+@synthesize name = _name;
+@synthesize location = _location;
+@synthesize bio = _bio;
+@synthesize tagline = _tagline;
+@synthesize website = _website;
+@synthesize githubUrl = _githubUrl;
+@synthesize gravatarHash = _gravatarHash;
+
+@synthesize loadingGravatar = _loadingGravatar;
+@synthesize gravatar = _gravatar;
+
+static NSOperationQueue *sharedGravatarOperationQueue() {
+ static NSOperationQueue *sharedGravatarOperationQueue = nil;
+ if (sharedGravatarOperationQueue == nil) {
+ sharedGravatarOperationQueue = [[NSOperationQueue alloc] init];
+ }
+ return sharedGravatarOperationQueue;
+}
+
+- (NSURL *)gravatarUrl {
+ return [NSURL URLWithString:[NSString stringWithFormat:@"http://gravatar.com/avatar/%@.png?s=40", self.gravatarHash]];
+}
+
+- (void)loadGravatar {
+ @synchronized (self) {
+ if (self.gravatar == nil && !self.loadingGravatar) {
+ self.loadingGravatar = YES;
+ [sharedGravatarOperationQueue() addOperationWithBlock:^(void) {
+ NSData *imageData = [NSData dataWithContentsOfURL:[self gravatarUrl]];
+ UIImage *image = [UIImage imageWithData:imageData];
+ if (image != nil) {
+ @synchronized (self) {
+ self.loadingGravatar = NO;
+ self.gravatar = image;
+ }
+ } else {
+ @synchronized (self) {
+ self.gravatar = nil;
+ }
+ }
+ }];
+ }
+ }
+}
+
@end
Oops, something went wrong.

0 comments on commit 1172eb9

Please sign in to comment.