2010-07-28 15 views
17

Nella mia app, sto cercando di salvare e recuperare un'immagine nei dati principali. Sono in grado di salvare un'immagine dopo la convenzione di UIimage in NSData, ma quando sto cercando di ottenere un'immagine come NSData mostra l'output come indicato di seguito,Salvataggio e recupero di una UIImage su CoreData

caso 1: quando si tenta di visualizzare come una stringa da DB.

<Event: 0x5b5d610> (entity: Event; id: 0x5b5ce30 <x-coredata://F51BBF1D-6484-4EB6-8583-147E23D9FF7B/Event/p1> ; data: <fault>) 

caso 2: Quando si tenta di visualizzare come dati

[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' 

Il mio codice,

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"); 
} 

per recuperare,

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: Sopra l'errore è in arrivo quando andando a eseguire NSData * dataBytes = [[array objectAtIndex: 0] data]; linea. Data Model http://www.freeimagehosting.net/uploads/7c286931cc.png

Ho trascorso molto tempo con questo. Per favore aiutatemi!

+0

Aggiungere codice relativo al modo in cui si inserisce l'immagine in NSData e come la si recupera. I messaggi di errore oscuri non aiutano molto – iwasrobbed

+0

@IWasRobbed ringraziano la tua risposta e ho messo il mio codice. per favore scopri cosa ho sbagliato che ho fatto. – Sivanathan

risposta

7

Quando si recupera l'immagine, si esegue la richiesta di recupero e si memorizzano i risultati nella variabile array, ovvero array contiene un oggetto NSArray di eventi. Poi, più tardi, si assegna:

dataBytes = [array objectAtIndex:0];

Ciò significa che dataBytes, che dichiarato come NSData, è ora in realtà un esempio di evento. Quindi, quando si avvia l'inizializzazione dell'immagine, parte dell'implementazione di imageWithData: chiama length su quello che si aspetta sia l'oggetto NSData, ma in realtà è un oggetto Event, quindi il messaggio di errore.

Si dovrebbe regolare il codice per leggere:

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

In questo modo, che stai ricevendo il primo oggetto Event fuori della matrice, quindi andare a prendere la sua proprietà imgPng (un'istanza di NSData, che è quello che si volere).

Come nota a margine, la vostra dichiarazione di dataBytes utilizzando il alloc - init sulla linea di cui sopra può essere estranea, dal momento che si cambia dataBytes essere i dati dal vostro evento subito dopo.

+0

@Tim Ho cambiato come hai detto, ma mostra ancora lo stesso errore. – Sivanathan

+0

Lo * esatto * stesso errore? Puoi modificare la tua domanda sopra e copiare/incollare l'errore dopo l'aggiornamento in esso? Grazie. – Tim

+0

@Tim ya sicuramente incollerò e grazie alla tua risposta – Sivanathan

39

Non sono sicuro se hai ottenuto questo raddrizzato fuori ancora, ma sono in grado di salvare/recuperare UIImage oggetti in Core Data come segue:

Per salvare:

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

e per caricare:

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

Spero che questo aiuti. Sto usando un UITableView con Core Data e sto prelevando l'immagine dal database nel mio metodo tableView:didSelectRowAtIndexPath:.

+1

Adoro i codici di esempio. Tuttavia, sarebbe bello dire che yourUIImage è di tipo UIImage * –

26

Ecco la soluzione corretta che funziona molto bene.

1) Memorizzazione UIImage con Core Data:

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

Assicurarsi che "coreDataImage" è di tipo NSData. Devi impostare il tipo su "Dati binari" per "coreDataImage" nel tuo modello.

2) Recupero di UIImage da Core Data:

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

Questo è tutto c'è ad esso, funziona alla grande.

+1

Scusa, non ho visto che Brian ha già risposto con quasi la stessa identica soluzione. – Detra83

+1

Non è necessario passare UIImagePNGRepresentation all'inizializzatore NSData poiché restituisce già un oggetto NSData. – Gargoyle

7

La soluzione che ho usato è stata quella di creare la categoria muggito. Ne hai solo bisogno nel tuo progetto perché funzioni. L'utilizzo di questo la memorizzazione delle immagini funziona proprio come voi dove memorizzare 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ì, questo è il modo più semplice, perché se una classe è conforme al protocollo NSCoding, è possibile utilizzare NSKeyedUnarchiveFromDataTransformerName (lo standard per i dati di base). – CarlJ

+0

Sono confuso. In nessun posto viene utilizzato NSKeyedUnarchiveFromDataTransformerName. –

+0

In realtà UIImage è già conforme a NSCoding senza bisogno di aggiungere alcun codice. Quindi può essere usato come attributo 'Trasformabile'. vedere [Memorizzare UIImage in CoreData senza scrivere alcun codice] (http://ootips.org/yonat/uiimage-in-coredata/) – Yonat

Problemi correlati