views:

507

answers:

2

In my app, I am trying to save and retrieval of an image in core data. I am able to save an image successfully after convention of UIimage into NSData, But when I am trying to get an image as NSData it shows output as given below,

case 1: When trying to display as a string from DB.

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

case 2: When trying to display as Data

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

My code,

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

to retrieve,

    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'

Note: Above error is coming when going to execute NSData * dataBytes = [[array objectAtIndex:0] data]; line. Data Model

I spent a lot of time with this. Please help me out!

+3  A: 

When you retrieve the image, you're performing the fetch request and storing the results in the variable array, meaning array holds an NSArray of Event objects. Then, later, you assign:

dataBytes = [array objectAtIndex:0];

This means that dataBytes, which you declared as NSData, is now actually an instance of Event. Then when you go to initialize the image, part of the implementation of imageWithData: calls length on what it expects to be your NSData object, but is actually an Event object, hence the error message.

You should adjust your code to read:

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

That way, you're getting the first Event object out of the array, then fetching its imgPng property (an instance of NSData, which is what you want).

As a side note, your declaration of dataBytes using the alloc-init on the line above may be extraneous, since you change dataBytes to be the data from your Event immediately afterwards.

Tim
@Tim I changed as you said, but still it shows same error.
Sivanathan
The *exact* same error? Can you edit your question above and copy/paste the error after the update into it? Thanks.
Tim
@Tim ya sure I will paste and thanks to your response
Sivanathan
@Sivanathan - note that's a slightly different error: this time, the Event object is getting the unrecognized selector `data`, not `length`. At least this means we're on the right track. Can you post either the code for your Event class (it should have been generated by Core Data) or a screenshot of your Core Data model? Specifically, I'm looking for the name of the getter for the `data` property of Event.
Tim
@Tim - I attached my data model screen shot and point out me if i have done any wrong
Sivanathan
@Sivanathan - ok, this one was my mistake. Instead of the `data` property, use the `imgPng` property from your model. (I got taken in by all the data accessors on NSData and didn't think to look at your `setValue:forKey:` call in your first block of code.) I've edited my answer to reflect this.
Tim
@Tim I really thanks to you. i have changed imgPng and it working fine
Sivanathan
@Sivanathan - no problem. Glad it's all working :)
Tim
A: 

Not sure if you've gotten this straightened out yet, but I am able to save/retrieve UIImage objects in Core Data as follows:

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

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

Hope this helps. I am using a UITableView with Core Data and pulling the image from the database in my tableView:didSelectRowAtIndexPath method.

Brian Williams