iphone - Guardar y recuperar un UIImage en CoreData
objective-c core-data (5)
En mi aplicación, estoy tratando de guardar y recuperar una imagen en datos básicos. Puedo guardar una imagen con éxito después de la convención de UIimage en NSData, pero cuando intento obtener una imagen como NSData, se muestra la salida como se muestra a continuación.
caso 1: cuando se intenta mostrar como una cadena desde DB.
<Event: 0x5b5d610> (entity: Event; id: 0x5b5ce30 <x-coredata://F51BBF1D-6484-4EB6-8583-147E23D9FF7B/Event/p1> ; data: <fault>)
caso 2: cuando se intenta mostrar como datos
[Event length]: unrecognized selector sent to instance 0x5b3a9c0
2010-07-28 19:11:59.610 IMG_REF[10787:207] *** Terminating app due to uncaught exception ''NSInvalidArgumentException'', reason: ''-[Event length]: unrecognized selector sent to instance 0x5b3a9c0''
Mi código,
to save:
NSManagedObjectContext *context = [self managedObjectContext];
newsObj = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context];
NSURL *url = [NSURL URLWithString:@"http://www.cimgf.com/images/photo.PNG"];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
uiImage = [UIImage imageWithData:data];
NSData * imageData = UIImagePNGRepresentation(uiImage);
[newsObj setValue:imageData forKey:@"imgPng"];
NSError *error;
@try{
if (managedObjectContext != nil) {
if (![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
NSString * infoString = [NSString stringWithFormat:@"Please check your connection and try again."];
UIAlertView * infoAlert = [[UIAlertView alloc] initWithTitle:@"Database Connection Error" message:infoString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[infoAlert show];
[infoAlert release];
}
}
}@catch (NSException *exception) {
NSLog(@"inside exception");
}
para recuperar
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity1 = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:context];
[fetchRequest setEntity:entity1];
NSError *error;
NSArray * array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (array == nil) {
NSLog(@"Testing: No results found");
}else {
NSLog(@"Testing: %d Results found.", [array count]);
}
NSData * dataBytes = [[array objectAtIndex:0] data];
image = [UIImage imageWithData:dataBytes];
[fetchRequest release];
}
@catch (NSException *exception) {
NSLog(@"inside exception");
}
Error:
Testing: 3 Results found.
2010-07-28 23:27:51.343 IMG_REF[11657:207] -[Event data]: unrecognized selector sent to instance 0x5e22ce0
2010-07-28 23:27:51.344 IMG_REF[11657:207] *** Terminating app due to uncaught exception ''NSInvalidArgumentException'', reason: ''-[Event data]: unrecognized selector sent to instance 0x5e22ce0''
*** Call stack at first throw:
(
0 CoreFoundation 0x02566919 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x026b45de objc_exception_throw + 47
2 CoreFoundation 0x0256842b -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x024d8116 ___forwarding___ + 966
4 CoreFoundation 0x024d7cd2 _CF_forwarding_prep_0 + 50
5 IMG_REF 0x00003b06 -[IMG_REFViewController showAction] + 353
6 UIKit 0x002bae14 -[UIApplication sendAction:to:from:forEvent:] + 119
7 UIKit 0x004c214b -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 156
8 UIKit 0x002bae14 -[UIApplication sendAction:to:from:forEvent:] + 119
9 UIKit 0x003446c8 -[UIControl sendAction:to:forEvent:] + 67
10 UIKit 0x00346b4a -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
11 UIKit 0x003456f7 -[UIControl touchesEnded:withEvent:] + 458
12 UIKit 0x002de2ff -[UIWindow _sendTouchesForEvent:] + 567
13 UIKit 0x002c01ec -[UIApplication sendEvent:] + 447
14 UIKit 0x002c4ac4 _UIApplicationHandleEvent + 7495
15 GraphicsServices 0x02dccafa PurpleEventCallback + 1578
16 CoreFoundation 0x02547dc4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
17 CoreFoundation 0x024a8737 __CFRunLoopDoSource1 + 215
18 CoreFoundation 0x024a59c3 __CFRunLoopRun + 979
19 CoreFoundation 0x024a5280 CFRunLoopRunSpecific + 208
20 CoreFoundation 0x024a51a1 CFRunLoopRunInMode + 97
21 GraphicsServices 0x02dcb2c8 GSEventRunModal + 217
22 GraphicsServices 0x02dcb38d GSEventRun + 115
23 UIKit 0x002c8b58 UIApplicationMain + 1160
24 IMG_REF 0x00002aac main + 102
25 IMG_REF 0x00002a3d start + 53
)
terminate called after throwing an instance of ''NSException''
Nota: el error anterior aparece cuando se ejecuta NSData * dataBytes = [[array objectAtIndex: 0] data]; línea. Modelo de datos http://www.freeimagehosting.net/uploads/7c286931cc.png
Pasé mucho tiempo con esto. ¡Por favor, ayúdame!
Aquí está la solución adecuada que funciona muy bien.
1) Almacenamiento de UIImage con datos básicos:
NSData* coreDataImage = [NSData dataWithData:UIImagePNGRepresentation(delegate.dancePhoto)];
Asegúrese de que "coreDataImage" sea de tipo NSData
. Debe establecer el tipo en "Datos binarios" para "CoreDataImage" en su modelo.
2) Recuperando UIImage de los Datos del Core:
UIImage* image = [UIImage imageWithData:selectedDance.danceImage];
Eso es todo lo que hay que hacer, funciona muy bien.
Cuando recupera la imagen, está realizando la solicitud de recuperación y almacenando los resultados en la array
variable, lo que significa que la array
contiene una NSArray de objetos de evento. Luego, más tarde, le asigna:
dataBytes = [array objectAtIndex:0];
Esto significa que dataBytes
, que declaró como NSData, ahora es en realidad una instancia de Evento. Luego, cuando vaya a inicializar la imagen, parte de la implementación de imageWithData:
llama a la length
de lo que espera que sea su objeto NSData, pero en realidad es un objeto de Evento, de ahí el mensaje de error.
Debes ajustar tu código para leer:
dataBytes = [[array objectAtIndex:0] imgPng];
De esa manera, obtendrás el primer objeto de Evento fuera de la matriz y luego imgPng
su propiedad imgPng
(una instancia de NSData, que es lo que quieres).
Como nota al margen, su declaración de dataBytes
utilizando el alloc
- init
en la línea anterior puede ser extraña, ya que cambia los dataBytes
para que sean los datos de su Evento inmediatamente después.
Este código de ejemplo tiene un ejemplo de cómo almacenar UIImage en Core Data: https://developer.apple.com/library/ios/#samplecode/PhotoLocations/Introduction/Intro.html
La solución que utilicé fue crear la siguiente categoría. Solo lo necesitas en tu proyecto para que funcione. El uso de este almacenamiento de imágenes funciona igual que en el almacenamiento de un NSData
UIImage + NSCoding.h
@interface UIImage (UIImage_NSCoding) <NSCoding>
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;
@end
UIImage + NSCoding.m
#import "UIImage+NSCoding.h"
@implementation UIImage (UIImage_NSCoding)
- (void)encodeWithCoder:(NSCoder *)aCoder
{
NSData *imageData = UIImagePNGRepresentation(self);
[aCoder encodeDataObject:imageData];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
[self autorelease];
NSData* imageData = [aDecoder decodeDataObject];
self = [[UIImage alloc] initWithData:imageData];
return self;
}
@end
No estoy seguro de haber solucionado esto todavía, pero puedo guardar / recuperar objetos UIImage
en Core Data de la siguiente manera:
Ahorrar:
NSData *imageData = UIImagePNGRepresentation(yourUIImage);
[newManagedObject setValue:imageData forKey:@"image"];
y para cargar:
NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
UIImage *image = [UIImage imageWithData:[selectedObject valueForKey:@"image"]];
[[newCustomer yourImageView] setImage:image];
Espero que esto ayude. Estoy utilizando un UITableView
con Core Data y UITableView
la imagen de la base de datos en mi tableView:didSelectRowAtIndexPath:
.