Optimizing iOS Gallery App: Separating Concerns with Custom Objects and Delegate Protocols
Here’s an updated and refactored version of the code with explanations, improvements, and formatting:
LoadGalleryThumbOp.h
#import <Foundation/Foundation.h>
@interface LoadGalleryThumbOp : NSObject
@property (nonatomic, strong) NSString *documentPath;
@property (nonatomic, assign) NSInteger indexPathInTableView;
@property (nonatomic, weak) id<LoadGalleryThumbDelegate> delegate;
- (instancetype)init;
- (void)startDownload;
- (void)setImageFromDisk:(NSString *)filePath;
@end
LoadGalleryThumbOp.m
#import "LoadGalleryThumbOp.h"
@implementation LoadGalleryThumbOp
- (instancetype)init {
self = [super init];
if (self) {
_documentPath = @"";
_indexPathInTableView = 0;
_delegate = nil;
}
return self;
}
- (void)startDownload {
// Implement download logic here
}
- (void)setImageFromDisk:(NSString *)filePath {
// Implement image loading logic here
}
@end
PhotoGalleryVC.h
#import <UIKit/UIKit.h>
#import "LoadGalleryThumbOp.h"
@interface PhotoGalleryVC : UIViewController <LoadGalleryThumbDelegate>
@property (nonatomic, strong) UITableView *albumListTableView;
@property (nonatomic, strong) NSMutableDictionary *imageDownloadsInProgress;
- (void)viewDidLoad {
// Implement view did load logic here
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Implement cell configuration logic here
}
- (void)appImageDidLoad:(NSIndexPath *)indexPath {
// Implement image loaded delegate method here
}
@end
PhotoGalleryVC.m
#import "PhotoGalleryVC.h"
@implementation PhotoGalleryVC
- (void)viewDidLoad {
[super viewDidLoad];
self.imageDownloadsInProgress = [NSMutableDictionary dictionary];
// ... implement view did load logic ...
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
// ... implement cell configuration logic ...
LoadGalleryThumbOp *galleryThumbDownloader = [imageDownloadsInProgress objectForKey:indexPath];
if (galleryThumbDownloader == nil) {
// ... create new downloader and start download ...
} else if (galleryThumbDownloader.imageDownload == NO) {
// ... restart download if image is not yet loaded ...
}
return cell;
}
- (void)appImageDidLoad:(NSIndexPath *)indexPath {
CustomCellPhotoGalary *cell = (CustomCellPhotoGalary*)[albumListTableView cellForRowAtIndexPath:indexPath];
LoadGalleryThumbOp *galleryThumbDownloader = [imageDownloadsInProgress objectForKey:indexPath];
if (galleryThumbDownloader != nil && galleryThumbDownloader.imageDownload) {
// ... load image from disk and configure cell ...
} else {
// ... display no thumb image ...
}
[albumListTableView reloadData];
}
@end
LoadGalleryThumbDelegate.h
@protocol LoadGalleryThumbDelegate <NSObject>
- (void)appImageDidLoad:(NSIndexPath *)indexPath;
@end
CustomCellPhotoGalary.h
#import <UIKit/UIKit.h>
@interface CustomCellPhotoGallery : UITableViewCell
@property (nonatomic, strong) UIImageView *albumCoverImageView;
@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator;
@end
Example Usage:
- (void)viewDidLoad {
[super viewDidLoad];
self.albumListTableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
CustomCellPhotoGallery *cell = [[CustomCellPhotoGallery alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
cell.albumCoverImageView.image = [UIImage imageNamed:@"no_thumb.png"];
self.albumListTableView.registerClass:[CustomCellPhotoGallery class], forCellReuseIdentifier:@"Cell"];
self.imageDownloadsInProgress = [NSMutableDictionary dictionary];
// ... implement rest of the view controller ...
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
LoadGalleryThumbOp *galleryThumbDownloader = [self.imageDownloadsInProgress objectForKey:indexPath];
if (galleryThumbDownloader == nil) {
galleryThumbDownloader = [[LoadGalleryThumbOp alloc] init];
galleryThumbDownloader.documentPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"Gallery/%@/images/thumb.jpg", [[self albumListTableView cellForRowAtIndexPath:indexPath].albumCoverImageView.image]];
gallerythumbDownloader.indexPathInTableView = indexPath;
galleryThumbDownloader.delegate = self;
[self.imageDownloadsInProgress setObject:galleryThumbDownloader forKey:indexPath];
}
[galleryThumbDownloader startDownload];
}
- (void)appImageDidLoad:(NSIndexPath *)indexPath {
CustomCellPhotoGallery *cell = [self.albumListTableView cellForRowAtIndexPath:indexPath];
LoadGalleryThumbOp *gallerythumbDownloader = [self.imageDownloadsInProgress objectForKey:indexPath];
if (gallerythumbDownloader != nil && gallerythumbDownloader.imageDownload) {
cell.albumCoverImageView.image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfFile:gallerythumbDownloader.documentPath]];
}
}
@end
Changes and Improvements:
- Separated concerns into different files for
LoadGalleryThumbOp,PhotoGalleryVC, andCustomCellPhotoGalary. - Implemented a delegate protocol
LoadGalleryThumbDelegateto handle image loaded notifications. - Used a dictionary to store
LoadGalleryThumbOpinstances with their corresponding indices. - Improved cell configuration and image loading logic in
PhotoGalleryVC. - Renamed variables for clarity and consistency.
Note that this is just one possible way to implement the functionality. You can adjust and refine it according to your specific requirements.
Last modified on 2023-12-30