2010-07-28 27 views
17

En mi aplicación, intento guardar y recuperar una imagen en los datos principales. Puedo guardar una imagen satisfactoriamente después de la convención de UIimage en NSData, pero cuando intento obtener una imagen como NSData muestra la salida como se indica a continuación,Guardar y recuperar un UIImage en CoreData

caso 1: cuando intento 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: Al intentar 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: Por encima de error viene cuando va a ejecutar NSData * dataBytes = [[array objectAtIndex: 0] data]; línea. Data Model http://www.freeimagehosting.net/uploads/7c286931cc.png

Pasé mucho tiempo con esto. ¡Por favor, ayúdame!

+0

Agregue el código correspondiente a cómo coloca la imagen en NSData y cómo la recupera. Los mensajes de error oscuros no ayudan mucho – iwasrobbed

+0

@ IWasRobbed gracias a su respuesta y puse mi código. Por favor, averigua qué está mal que he hecho. – Sivanathan

Respuesta

7

Cuando recupera la imagen, está realizando la solicitud de búsqueda y almacenando los resultados en la variable array, lo que significa que array contiene un NSArray de objetos Evento. Luego, más tarde, se asigna:

dataBytes = [array objectAtIndex:0];

Esto significa que dataBytes, los que haya declarado como NSData, ahora es realmente una instancia de Evento. Luego, cuando vaya a inicializar la imagen, parte de la implementación de imageWithData: llama al length en lo que espera que sea su objeto NSData, pero en realidad es un objeto Evento, de ahí el mensaje de error.

Usted debe ajustar su código para leer:

dataBytes = [[array objectAtIndex:0] imgPng];

esta manera, usted está recibiendo el primer objeto de eventos fuera de la matriz, y luego ir a buscar su imgPng propiedad (una instancia de NSData, que es lo que querer).

Como nota al margen, su declaración de dataBytes utilizando el alloc - init en la línea anterior puede ser ajeno, ya que cambia dataBytes a ser los datos de su evento inmediatamente después.

+0

@Tim He cambiado como dijiste, pero igual muestra el mismo error. – Sivanathan

+0

El * exacto * mismo error? ¿Puedes editar tu pregunta anterior y copiar/pegar el error después de la actualización? Gracias. – Tim

+0

@Tenga en cuenta que voy a pegar y gracias a su respuesta – Sivanathan

39

No estoy seguro si usted ha conseguido este embrollo todavía, pero soy capaz de guardar/recuperar UIImage objetos en la base de datos de la siguiente manera:

Para guardar:

NSData *imageData = UIImagePNGRepresentation(yourUIImage); 
[newManagedObject setValue:imageData forKey:@"image"]; 

y para la carga:

NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath]; 
UIImage *image = [UIImage imageWithData:[selectedObject valueForKey:@"image"]]; 
[[newCustomer yourImageView] setImage:image]; 

Espero que esto ayude. Estoy usando un UITableView con Core Data y extraigo la imagen de la base de datos en mi método tableView:didSelectRowAtIndexPath:.

+1

Me encantan los códigos de muestra. Sin embargo, sería bueno mencionar que tu UIImage es del tipo UIImage * –

26

Aquí está la solución adecuada que funciona muy bien.

1) Almacenamiento UIImage con datos básicos:

NSData* coreDataImage = [NSData dataWithData:UIImagePNGRepresentation(delegate.dancePhoto)]; 

Asegúrese de que "coreDataImage" es de tipo NSData. Debe establecer el tipo de "Datos binarios" para "coreDataImage" en su modelo.

2) Recuperación de UIImage de datos básicos:

UIImage* image = [UIImage imageWithData:selectedDance.danceImage]; 

Eso es todo lo que hay a la misma, funciona muy bien.

+1

Lo siento, pero no veo que Brian ya haya respondido con casi la misma solución. – Detra83

+1

No es necesario pasar UIImagePNGRpresentación al inicializador NSData ya que devuelve un objeto NSData. – Gargoyle

7

La solución que utilicé fue crear la categoría siguiente. Lo necesitas en tu proyecto para que funcione. El uso de este almacenamiento de imágenes funciona igual que en el almacenamiento de un

#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 
+0

sí, esta es la manera más fácil, porque si una clase cumple con el protocolo NSCoding, entonces se puede usar NSKeyedUnarchiveFromDataTransformerName (el estándar para datos básicos). – CarlJ

+0

Estoy confundido. En ninguna parte se usa NSKeyedUnarchiveFromDataTransformerName. –

+0

En realidad UIImage ya se ajusta a NSCoding sin la necesidad de agregar ningún código. Por lo tanto, se puede usar como un atributo 'Transformable'. ver [Almacenar UIImage en CoreData sin escribir ningún código] (http://ootips.org/yonat/uiimage-in-coredata/) – Yonat

Cuestiones relacionadas