[New Example] 500pxgram

- added UIActivityMonitor
- added simple NSCache for UIKit tab
This commit is contained in:
Hannah Troisi
2016-04-11 19:04:05 -07:00
parent 89ab6b38fc
commit 23d00d40e1
7 changed files with 102 additions and 34 deletions

View File

@@ -64,15 +64,16 @@
return YES;
}
// UITabBarControllerDelegate
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;
#pragma mark - UITabBarControllerDelegate
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[UINavigationController class]]) {
NSArray *viewControllers = [(UINavigationController *)viewController viewControllers];
UIViewController *rootViewController = viewControllers[0];
if ([rootViewController conformsToProtocol:@protocol(PhotoFeedControllerProtocol)]) {
// FIXME: the dataModel does not currently handle clearing data during loading properly
// [(id <PhotoFeedViewControllerProtocol>)rootViewController resetAllData];
// [(id <PhotoFeedControllerProtocol>)rootViewController resetAllData];
}
}
}

View File

@@ -29,8 +29,9 @@
NSUInteger _totalItems;
BOOL _fetchPageInProgress;
BOOL _refreshFeedInProgress;
CLLocationCoordinate2D _location;
NSURLSessionDataTask *_task;
CLLocationCoordinate2D _location;
NSUInteger _locationRadius;
NSUInteger _userID;
}
@@ -123,7 +124,12 @@
- (void)clearFeed
{
_photos = [[NSMutableArray alloc] init];
_ids = [[NSMutableArray alloc] init];
_ids = [[NSMutableArray alloc] init];
_currentPage = 0;
_fetchPageInProgress = NO;
_refreshFeedInProgress = NO;
[_task cancel];
_task = nil;
}
- (void)requestPageWithCompletionBlock:(void (^)(NSArray *))block numResultsToReturn:(NSUInteger)numResults
@@ -185,7 +191,7 @@
NSString *urlAdditions = [NSString stringWithFormat:@"&page=%lu&rpp=%lu%@", (unsigned long)nextPage, (long)numPhotos, imageSizeParam];
NSURL *url = [NSURL URLWithString:[_urlString stringByAppendingString:urlAdditions]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
_task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data) {
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
@@ -223,8 +229,8 @@
}
_fetchPageInProgress = NO;
});
}]; // end task
[task resume];
}];
[_task resume];
}
});
}

View File

@@ -20,8 +20,9 @@
@implementation PhotoFeedNodeController
{
PhotoFeedModel *_photoFeed;
ASTableNode *_tableNode;
PhotoFeedModel *_photoFeed;
ASTableNode *_tableNode;
UIActivityIndicatorView *_activityIndicatorView;
}
#pragma mark - Lifecycle
@@ -35,12 +36,10 @@
self.navigationItem.title = @"ASDK";
[self.navigationController setNavigationBarHidden:YES];
_photoFeed = [[PhotoFeedModel alloc] initWithPhotoFeedModelType:PhotoFeedModelTypePopular
imageSize:[self imageSizeForScreenWidth]];
[self refreshFeed];
_tableNode.dataSource = self;
_tableNode.delegate = self;
_activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
}
return self;
@@ -51,20 +50,35 @@
{
[super loadView];
_photoFeed = [[PhotoFeedModel alloc] initWithPhotoFeedModelType:PhotoFeedModelTypePopular imageSize:[self imageSizeForScreenWidth]];
[self refreshFeed];
CGSize boundSize = self.view.bounds.size;
[_activityIndicatorView sizeToFit];
CGRect refreshRect = _activityIndicatorView.frame;
refreshRect.origin = CGPointMake((boundSize.width - _activityIndicatorView.frame.size.width) / 2.0,
(boundSize.height - _activityIndicatorView.frame.size.height) / 2.0);
_activityIndicatorView.frame = refreshRect;
[self.view addSubview:_activityIndicatorView];
self.view.backgroundColor = [UIColor whiteColor];
_tableNode.view.allowsSelection = NO;
_tableNode.view.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableNode.view.leadingScreensForBatching = AUTO_TAIL_LOADING_NUM_SCREENFULS; // overriding default of 2.0
}
#pragma mark - helper methods
- (void)refreshFeed
{
[_activityIndicatorView startAnimating];
// small first batch
[_photoFeed refreshFeedWithCompletionBlock:^(NSArray *newPhotos){
[_activityIndicatorView stopAnimating];
[self insertNewRowsInTableView:newPhotos];
[self requestCommentsForPhotos:newPhotos];

View File

@@ -19,8 +19,9 @@
@implementation PhotoFeedViewController
{
PhotoFeedModel *_photoFeed;
UITableView *_tableView;
PhotoFeedModel *_photoFeed;
UITableView *_tableView;
UIActivityIndicatorView *_activityIndicatorView;
}
#pragma mark - Lifecycle
@@ -38,8 +39,7 @@
_tableView.delegate = self;
_tableView.dataSource = self;
_photoFeed = [[PhotoFeedModel alloc] initWithPhotoFeedModelType:PhotoFeedModelTypePopular imageSize:[self imageSizeForScreenWidth]];
[self refreshFeed];
_activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
}
return self;
@@ -50,19 +50,38 @@
{
[super viewDidLoad];
_photoFeed = [[PhotoFeedModel alloc] initWithPhotoFeedModelType:PhotoFeedModelTypePopular imageSize:[self imageSizeForScreenWidth]];
[self refreshFeed];
CGSize boundSize = self.view.bounds.size;
[self.view addSubview:_tableView];
_tableView.frame = self.view.bounds;
_tableView.allowsSelection = NO;
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[_tableView registerClass:[PhotoTableViewCell class] forCellReuseIdentifier:@"photoCell"];
[self.view addSubview:_activityIndicatorView];
[_activityIndicatorView sizeToFit];
CGRect refreshRect = _activityIndicatorView.frame;
refreshRect.origin = CGPointMake((boundSize.width - _activityIndicatorView.frame.size.width) / 2.0,
(boundSize.height - _activityIndicatorView.frame.size.height) / 2.0);
_activityIndicatorView.frame = refreshRect;
}
#pragma mark - helper methods
- (void)refreshFeed
{
[_activityIndicatorView startAnimating];
// small first batch
[_photoFeed refreshFeedWithCompletionBlock:^(NSArray *newPhotos){
[_activityIndicatorView stopAnimating];
[self insertNewRowsInTableView:newPhotos];
[self requestCommentsForPhotos:newPhotos];

View File

@@ -437,11 +437,9 @@
rect.size = [_photoDescriptionLabel sizeThatFits:CGSizeMake(availableWidth, CGFLOAT_MAX)];
_photoDescriptionLabel.frame = rect;
[[PINRemoteImageManager sharedImageManager] downloadImageWithURL:photo.URL
options:PINRemoteImageManagerDownloadOptionsSkipDecode
completion:^(PINRemoteImageManagerResult * _Nonnull result) {
_photoImageView.image = result.image;
}];
[UIImage downloadImageForURL:photo.URL completion:^(UIImage *image) {
_photoImageView.image = image;
}];
[self downloadAndProcessUserAvatarForPhoto:photo];
[self loadCommentsForPhoto:photo];
@@ -467,15 +465,10 @@
- (void)downloadAndProcessUserAvatarForPhoto:(PhotoModel *)photo
{
[[PINRemoteImageManager sharedImageManager] downloadImageWithURL:_photoModel.ownerUserProfile.userPicURL
options:PINRemoteImageManagerDownloadOptionsSkipDecode
processorKey:@"custom"
processor:^UIImage * _Nullable(PINRemoteImageManagerResult * _Nonnull result, NSUInteger * _Nonnull cost) {
CGSize profileImageSize = CGSizeMake(USER_IMAGE_HEIGHT, USER_IMAGE_HEIGHT);
return [result.image makeCircularImageWithSize:profileImageSize];
} completion:^(PINRemoteImageManagerResult * _Nonnull result) {
_userAvatarImageView.image = result.image;
}];
[UIImage downloadImageForURL:photo.URL completion:^(UIImage *image) {
CGSize profileImageSize = CGSizeMake(USER_IMAGE_HEIGHT, USER_IMAGE_HEIGHT);
_userAvatarImageView.image = [image makeCircularImageWithSize:profileImageSize];
}];
}
- (void)reverseGeocodeLocationForPhoto:(PhotoModel *)photo

View File

@@ -16,6 +16,7 @@
@interface UIImage (Additions)
+ (UIImage *)followingButtonStretchableImageForCornerRadius:(CGFloat)cornerRadius following:(BOOL)followingEnabled;
+ (void)downloadImageForURL:(NSURL *)url completion:(void (^)(UIImage *))block;
- (UIImage *)makeCircularImageWithSize:(CGSize)size;

View File

@@ -60,6 +60,40 @@
return followingBtnImageStretchable;
}
+ (void)downloadImageForURL:(NSURL *)url completion:(void (^)(UIImage *))block
{
static NSCache *simpleImageCache = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
simpleImageCache = [[NSCache alloc] init];
simpleImageCache.countLimit = 10;
});
if (!block) {
return;
}
// check if image is cached
UIImage *image = [simpleImageCache objectForKey:url];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
block(image);
});
} else {
// else download image
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data) {
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
block(image);
});
}
}];
[task resume];
}
}
- (UIImage *)makeCircularImageWithSize:(CGSize)size
{
// make a CGRect with the image's size