I'm trying to load a set of images from a web service to a UICollectionView
and I'm using MKNetworkKit
to handle the networking operations.
This is bit a of a strange problem because it works in one scenario and doesn't in another. Please bear with with me, this is bit of a long post.
I have a simple storyboard app with a UIViewController
with a UICollectionView
embedded as its main view (Can't use UICollectionViewController
due to a UI change I'm gonna do later).
I have created a class which is a subclass of MKNetworkEngine
to handle the method to retrieve the images from the web service.
ImageEngine.h
#import "MKNetworkEngine.h"
@interface ImageEngine : MKNetworkEngine
typedef void (^ImagesResponseBlock)(NSMutableArray *imageURLs);
- (void)allImages:(ImagesResponseBlock)imageURLBlock errorHandler:(MKNKErrorBlock)errorBlock;
@end
ImageEngine.m
#import "ImageEngine.h"
@implementation ImageEngine
- (void)allImages:(ImagesResponseBlock)imageURLBlock errorHandler:(MKNKErrorBlock)errorBlock
{
MKNetworkOperation *op = [self operationWithPath:@"All_Images.php"];
[op addCompletionHandler:^(MKNetworkOperation *completedOperation) {
[completedOperation responseJSONWithCompletionHandler:^(id jsonObject) {
imageURLBlock(jsonObject[@"Images"]);
}];
} errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {
errorBlock(error);
}];
[self enqueueOperation:op];
}
- (NSString *)cacheDirectoryName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = paths[0];
NSString *cacheDirectoryName = [documentsDirectory stringByAppendingPathComponent:@"SomeImages"];
return cacheDirectoryName;
}
@end
In the view controller class with the collection view,
#import "AppDelegate.h"
#import "GridViewController.h"
#import "ImageCell.h"
@interface GridViewController () <UICollectionViewDelegate, UICollectionViewDataSource>
@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
@property (strong, nonatomic) NSMutableArray *images;
@property (strong, nonatomic) NSString *selectedImageUrl;
@end
@implementation GridViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[ApplicationDelegate.imageEngine allImages:^(NSMutableArray *images) {
self.images = images;
[self.collectionView reloadData];
} errorHandler:^(NSError *error) {
NSLog(@"MKNetwork Error: %@", error.localizedDescription);
}];
}
#pragma mark - UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.images.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *thisImage = self.images[indexPath.row];
self.selectedImageUrl = [NSString stringWithFormat:@"%@%@", @"http://toonmoodz.osmium.lk/", thisImage[@"image"]];
[cell.imageView setImageFromURL:[NSURL URLWithString:self.selectedImageUrl]];
return cell;
}
@end
This works just fine. The images load as expected.
Then I did a small UI upgrade to the app using MBPullDownController. It simply adds a table view under the collection view. No changes to the networking code. Just a new subclass of MBPullDownController
to embed the collection view and the table view in the main view controller.
But when I do that, the images don't load at all. I put a breakpoint inside the methods of the ImageEngine class to see if they get fired but it never comes to that. (The weird thing is this code actually worked fine just this morning. Now it doesn't and I have absolutely no idea why). It doesn't throw any errors or warnings either.
I have uploaded two projects demonstrating this issue so that it'll be easier for others to understand. If anyone can help me out, I'd be really grateful. I've been pulling my hair out for the past few hours on this.
Source of the version that's working correctly.
This is the source of the project that is with the issue. (When you run it, it'll show a blank white view. It looks like a plain view but it is the collection view. I loaded up a set of local images to see if its working and it does)
Thank you.
When I set breakpoint in GridViewController
in viewDidLoad
method, after executing po [[UIApplication sharedApplication] valueForKeyPath:@"delegate.imageEngine"]
in console I see that imageEngine
property is equal to nil.
It looks like application:didFinishLaunchingWithOptions
is being executed after viewDidLoad
in GridViewController
.
I removed those two lines from your application:didFinishLaunchingWithOptions
:
self.imageEngine = [[ImageEngine alloc] initWithHostName:@"toonmoodz.osmium.lk"];
[self.imageEngine useCache];
Then i've added imageEngine lazy loader to AppDelegate
and its working http://cl.ly/image/1S172D2e050J
- (ImageEngine*) imageEngine {
if (_imageEngine == nil) {
_imageEngine = [[ImageEngine alloc] initWithHostName:@"toonmoodz.osmium.lk"];
[_imageEngine useCache];
}
return _imageEngine;
}