Using Coredata to cache and display images via Instagram

To display images via instagram, I would be using CoreData and UITableViewController.
I choose to use table view controller, since the cells are automatically reused, instead of creating new ones. Also the memory allocation and deallocation is handled by the OS. For this tutorial we would display four photos in each row. Let me dive directly into the tutorial. First of all in your app delegate do the following:
WORDPRESS SUPPORT FOR CODE SUCKS, HENCE COULD NOT FORMAT THE CODE.
[sourcecode lang=”objc”]
(NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
– (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
return managedObjectModel;
}
– (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
stringByAppendingPathComponent: @"instagram.sqlite"]];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:[self managedObjectModel]];
if(![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:storeUrl options:nil error:&error]) {
/*Error for store creation should be handled in here*/
}
return persistentStoreCoordinator;
}
[/sourcecode]
We have basically created the three pillars of core data here. Context, model and persistentStoreCoordinator.
Inside your view controller, receive the context created in the app delegate –
[sourcecode lang=”objc”]
redflowerAppDelegate *appDelegate = (redflowerAppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = appDelegate.managedObjectContext;
// method to insert data into tables
-(void) addUrlsIntoDatabaseForId:(NSString*) photoId forUrl:(NSString*) url forData:(NSData*) data forTag:(int)startVal forHighRes:(NSString*) highResUrl{
NSManagedObject *newPhoto;
newPhoto = [NSEntityDescription insertNewObjectForEntityForName:@"Photos" inManagedObjectContext: self.managedObjectContext];
[newPhoto setValue:photoId forKey:@"photoId"];
[newPhoto setValue:url forKey:@"photoThumbnailUrl"];
[newPhoto setValue:data forKey:@"photoData"];
[newPhoto setValue:highResUrl forKey:@"photoHighResolutionUrl"];
[newPhoto setValue:[NSNumber numberWithInt:startVal ] forKey:@"tag"];
NSError *error;
[managedObjectContext save:&error];
}
// method to search for a photo in DB
-(NSData*) searchForId:(NSString*) photoId{
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"Photos"
inManagedObjectContext: managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"(photoId = %@)", photoId];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error];
if ([objects count] == 0) {
return nil;
} else {
matches = [objects objectAtIndex:0];
NSData* data = [matches valueForKey:@"photoData"];
// self.status.text = [NSString stringWithFormat: @"%d matches found", [objects count]];
return data;
}
return nil;
}
-(NSString*) getHighResolutionUrlForTag:(int) tag{
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"Photos"
inManagedObjectContext: managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"(tag = %d)", tag];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error];
if ([objects count] == 0) {
return @"";
} else {
matches = [objects objectAtIndex:0];
NSString* url = [matches valueForKey:@"photoHighResolutionUrl"];
// self.status.text = [NSString stringWithFormat: @"%d matches found", [objects count]];
return url;
}
return @"";
}
 
– (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = (UITableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIView* photoHolder;
UIImageView* imageView;
float leftOffset = 5.0;
float size = 70.0;
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// create views for 4 photos in each cell
}
UIView* subViewCell = cell.contentView;
int startVal = indexPath.row * 4;
for (UIView* imgView in [subViewCell subviews]) {
// put in the data in the cells
if (startVal < [photos count]) {
// set the image view in each subview in each row
for (id subView in [imgView subviews]) {
if ([subView isKindOfClass:[UIImageView class]]) {
photo* thumnailPhoto = [photos objectAtIndex:startVal];
UIImage* placeHolderImage = [UIImage imageNamed:@"placeholder.png"];
[subView setImage:placeHolderImage];
// if image is already in DB don’t add it
NSData* imageData = [self searchForId:thumnailPhoto.imageId];
if (imageData != nil) {
[subView setTag:startVal];
[subView setImage:[UIImage imageWithData:imageData]];
[subView setHidden:NO];
}else{
dispatch_async(imageQueue, ^{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString: thumnailPhoto.thumbnailUrl]];
dispatch_async(dispatch_get_main_queue(), ^{
[subView setTag:startVal];
[subView setImage:[UIImage imageWithData:imageData]];
[subView setHidden:NO];
// add data into DB
[self addUrlsIntoDatabaseForId:thumnailPhoto.imageId forUrl:thumnailPhoto.thumbnailUrl forData:imageData forTag:startVal
forHighRes:thumnailPhoto.highResolutionUrl];
});
});
}
startVal++;
}
}
// completion load the image view
}
}
return cell;
}
[/sourcecode]

Leave a Reply

Your email address will not be published. Required fields are marked *