从iOS CoreData中获取图像

时间:2012-12-25 00:25:08

标签: ios core-data uiimage

我有一个使用NSData属性imageData定义的核心数据实体。我在实体上设置了image的setter和getter。

设置者setImage只调用[self setImageData:UIImagePNGRepresentation(img)]; getter image只返回[UIImage imageWithData:[self imageData]];

当我创建一个新实体并且我的获取结果控制器加载新表格行时,图像总是拉空。但是,如果我点击该行转到下一个视图控制器,则图像显示正常

如何在保存发生后立即显示图像,并使用新行更新fetchResultsController。

编辑:添加代码

图片摘要的核心数据标头和getter / setter

.h
@property (nonatomic, retain) NSData * imageData;

@property (nonatomic, retain) UIImage *image;

.m
- (void)setImage:(UIImage *)image
{
    NSData *data = UIImagePNGRepresentation(image);
    [self setImageData:data];
}

- (UIImage *)image
{
    return [UIImage imageWithData:[self imageData]];
}

表视图代码

- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    [NSFetchedResultsController deleteCacheWithName:@"Artists"];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"ArtistModel" inManagedObjectContext:[[BKDataManager sharedInstance] mainObjectContext]];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetchRequest setFetchBatchSize:20];

    _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[[BKDataManager sharedInstance] mainObjectContext] sectionNameKeyPath:nil cacheName:@"Artists"];

    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ArtistTableViewCell *cell = (ArtistTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"ArtistsTableViewCell"];

    if(!cell) {
        cell = (ArtistTableViewCell *)[[[UINib nibWithNibName:@"ArtistTableViewCell" bundle:nil] instantiateWithOwner:nil options:nil] objectAtIndex:0];
    }

    ArtistModel *row = [[self fetchedResultsController] objectAtIndexPath:indexPath];

    [[cell artistNameLabel] setText:[row name]];
    [[cell artistImageView] setImage:[row image]]; // This is where it pulls from the artist model

    return cell;
}

保存到核心数据位

- (void)addArtistWithName:(NSString *)name confirmed:(BOOL)confirmed managedContext:(NSManagedObjectContext *)managedContext success:(BKClientIdResult)success failure:(BKClientError)failure
{
    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
                            name, @"name",
                            [NSNumber numberWithBool:confirmed], @"confirmed"
                            , nil];

    [[BKClient sharedInstance] postPath:@"/users/artists" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if([[responseObject objectForKey:@"status"] boolValue]) {
            NSDictionary *result = [responseObject valueForKeyPath:@"payload.artist"];

            ArtistModel *artistModel = (ArtistModel *)[NSEntityDescription insertNewObjectForEntityForName:@"ArtistModel" inManagedObjectContext:managedContext];

            [artistModel setName:[result objectForKey:@"name"]];

                NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:[result objectForKey:@"image"]]];

                AFImageRequestOperation *op = [AFImageRequestOperation imageRequestOperationWithRequest:imageRequest imageProcessingBlock:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                    [artistModel setImage:image];

                    [managedContext save:nil];

                    if(success) {
                        success(artistModel);
                    }
                } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
                    // TODO FIX
                }];

                [op start];
        } else {
            if(failure) {
                failure([NSError errorWithDomain:@"com.nf" code:0 userInfo:[responseObject objectForKey:@"error"]]);
            }
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        if(failure) {
            failure(error);
        }
    }];
}

2 个答案:

答案 0 :(得分:1)

根据您的问题,刷新数据的最简单方法是执行新的提取(通过NSFetchedResultsController)并在完成保存后重新加载表视图。

NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
    // error handling here...
}

[yourTableView reloadData];

或者,您可以考虑为NSFetchedResultsController设置委托。有关详细信息,请查看NSFetchedResultsControllerDelegate doccore-data-tutorial-how-to-use-nsfetchedresultscontroller

设置此委托,它允许您侦听托管上下文的更改并正确响应表视图修改(添加,删除,更新部分和行)。

P.S。如果您提供一些代码,我们将能够以更详细的方式为您提供帮助。

答案 1 :(得分:0)

您可以使用NSValueTransformer轻松将图像存储到CoreData中(使用Transformable类型而不是NSData):

·H

@interface ImageToDataTransformer : NSValueTransformer

@end

的.m

#import "DataTransformer.h"

@implementation ImageToDataTransformer

#pragma mark - UIImage to NSData

+ (BOOL)allowsReverseTransformation {
  return YES;
}

+ (Class)transformedValueClass {
  return [NSData class];
}

- (id)transformedValue:(id)value {
  NSData * data = UIImagePNGRepresentation(value);
  return data;
}

- (id)reverseTransformedValue:(id)value {
  UIImage * image = [[UIImage alloc] initWithData:value];
  return [image autorelease];
}

@end

不要忘记将您的属性设置为Transformable类型,然后在“数据模型检查器”中将名称设置为ImageToDataTransformer