在核心数据记录中显示uiwebview中的图像

时间:2011-10-01 19:02:09

标签: objective-c ios core-data uiwebview uiimage

所以我有一个我为iPad写的应用程序,我希望能够允许用户通过从相册或相机中选择图像将图像插入到他们的文档中。一切都很好。因为用户可能会将文档保留的时间长于将图像保留在相册中,所以我会复制它,将其缩小一点,然后将其存储在刚刚用于此目的的核心数据表中。

我存储的图像如下:

NSManagedObjectContext* moc=[(ActionNote3AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSString* imageName=[NSString stringWithFormat:@"img%lf.png",[NSDate  timeIntervalSinceReferenceDate]];
Image* anImage = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:moc];
anImage.imageName=imageName;
anImage.imageData=UIImagePNGRepresentation(theImage);
NSError* error=nil;
if(![moc save:&error]) {...

我在Cocoa With Love上建议的子类NSURLCache,以及ovverride cachedResponseForRequest:

- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
    NSString *pathString = [[[request URL] absoluteString]lastPathComponent];
    NSData* data = [Image dataForImage:pathString];
    if (!data) {
        return [super cachedResponseForRequest:request];
    }

    NSURLResponse *response =[[[NSURLResponse alloc] 
                               initWithURL:[request URL] 
                               MIMEType:[NSString stringWithString:@"image/png"] 
                               expectedContentLength:[data length] 
                               textEncodingName:nil] 
                              autorelease];
    NSCachedURLResponse* cachedResponse =[[[NSCachedURLResponse alloc] initWithResponse:response data:data] autorelease];

    return cachedResponse;
}

我还确保应用程序在didFinishLaunchingWithOptions中的app委托中使用子类NSURLCache:

ANNSUrlCache* uCache=[[ANNSUrlCache alloc]init];
[NSURLCache setSharedURLCache:uCache];

从核心数据记录返回图像数据的方法如下所示:

+(NSData*)dataForImage:(NSString *)name {
    NSData* retval=nil;
    NSManagedObjectContext* moc=[(ActionNote3AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Image" inManagedObjectContext:moc];
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"imageName==%@", name];
[request setPredicate:predicate];

    NSError* error=nil;
    NSArray *array = [moc executeFetchRequest:request error:&error];

    if ([array count]>0) {
        retval=((Image*)[array objectAtIndex:0]).imageData;
    }

    return retval;
}

要将图像插入Web视图,我有一个html img标记,其中src =“”中的名称与图像表中的名称相关。上面的NSURLCache代码的目的是观察我们存储在图像表中的名称,拦截它,并发送所请求图像的实际图像数据。

当我运行它时,我看到在我的子类NSURLCache对象中请求了图像。它找到了正确的记录,并按原样返回数据。但是,我仍然在我的uiwebview中找到未找到图像的图标:

Image for Image Not Found

所以Marcus(下面)建议我不要将图像数据存储在核心数据表中。所以我做了修改以适应这个:

存储图像:

NSString* iName=[NSString stringWithFormat:@"img%lf.png",[NSDate timeIntervalSinceReferenceDate]];
NSData* iData=UIImagePNGRepresentation(theImage);

NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* fullPathToFile = [documentsDirectory stringByAppendingPathComponent:iName];
[iData writeToFile:fullPathToFile atomically:NO];

检索图像:

- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
    NSString *pathString = [[[request URL] absoluteString]lastPathComponent];
    NSString* iPath = [Image pathForImage:pathString];
    if (!iPath) {
        return [super cachedResponseForRequest:request];
    }

    NSData* idata=[NSData dataWithContentsOfFile:iPath];

    NSURLResponse *response =[[[NSURLResponse alloc] 
                               initWithURL:[request URL] 
                               MIMEType:@"image/png" 
                               expectedContentLength:[idata length] 
                               textEncodingName:nil] 
                              autorelease];
    NSCachedURLResponse* cachedResponse =[[[NSCachedURLResponse alloc] initWithResponse:response data:idata] autorelease];

    return cachedResponse;
}

在调试模式下,我看到idata确实加载了正确的图像数据。

我仍然得到图像未找到的图像!显然,我在这里做错了。我只是不知道它是什么。

那么......我在这里做错了什么?我怎样才能让它正常工作?

谢谢。

2 个答案:

答案 0 :(得分:0)

强烈建议您不要将二进制数据存储在Core Data中。在Core Data中存储二进制数据,尤其是在iOS设备上,会导致缓存出现严重的性能问题。

首选方法是将实际二进制数据存储在磁盘上的文件中,并引用存储在Core Data中的文件。从那里,将图像URL更改为指向本地文件是一件简单的事情。

答案 1 :(得分:0)

所以事实证明我是在过度思考这个问题。当我编写HTML时,我只是使用图像标记写入图像的路径。奇迹般有效。

我很想知道为什么我在问题中提出的解决方案不起作用。

而且,我确实没有将图像存储在表格中。