Encoding custom classes using yajl-objc - iphone

Summary. Based on some benchmarks, I chose yajl-objc for my iPhone JSON parser. I was testing it with an arbitrary custom class (one NSNumber and two NSString properties). If I created an NSDictionary with key-value pairs matching the class properties, I could encode the dictionary with [dictionary yajl_JSON]. When I tried directly encoding an instance of the custom class with [custom yajl_JSON], I got this compiler error:
Terminating app due to uncaught exception 'YAJLParsingUnsupportedException', reason: 'Object of type (Custom) must implement dataUsingEncoding: to be parsed'.
I got the error even when I implemented - (id)JSON (as suggested in the yajl-objc readme). I know my code, not the library, is the problem. I just can't figure out what I'm doing wrong.
Details. My Custom.h:
#import
#interface Custom : NSObject {
NSString *name;
NSNumber *number;
NSString *text;
}
#property (nonatomic, copy) NSString *name;
#property (nonatomic, copy) NSNumber *number;
#property (nonatomic, copy) NSString *text;
#end
In Custom.m, I defined an - (id)JSON method per the yajl-obj documentation:
- (id)JSON
{
NSDictionary *jsonDictionary =
[[[NSMutableDictionary alloc] init] autorelease];
[jsonDictionary setValue:name forKey:#"name"];
[jsonDictionary setValue:number forKey:#"number"];
[jsonDictionary setValue:text forKey:#"text"];
return jsonDictionary;
}
Creating a key-value matched dictionary and encoding it works fine:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setValue:self.custom.name forKey:#"name"];
[dict setValue:self.custom.number forKey:#"number"];
[dict setValue:self.custom.text forKey:#"text"];
NSString *JSONString = [dict yajl_JSON];
But when I call NSString* JSONString = [custom yajl_JSON]; here's the compiler error and stack trace I get:
*** Terminating app due to uncaught exception 'YAJLParsingUnsupportedException', reason: 'Object of type (Custom) must implement dataUsingEncoding: to be parsed'
*** Call stack at first throw:
(
0 CoreFoundation 0x0266bb99 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x027bb40e objc_exception_throw + 47
2 CoreFoundation 0x02624238 +[NSException raise:format:arguments:] + 136
3 CoreFoundation 0x026241aa +[NSException raise:format:] + 58
4 TestCustomFileFormat 0x00005151 -[NSObject(YAJL) yajl_JSONWithOptions:error:] + 206
5 TestCustomFileFormat 0x00005212 -[NSObject(YAJL) yajl_JSON:] + 49
6 TestCustomFileFormat 0x00005249 -[NSObject(YAJL) yajl_JSON] + 49
7 TestCustomFileFormat 0x00002eba -[TestViewController loadInstruction] + 758
8 TestCustomFileFormat 0x00002aa5 -[TestViewController viewDidLoad] + 77
9 UIKit 0x0037585a -[UIViewController view] + 179
10 TestCustomFileFormat 0x00002377 -[TestCustomFileFormatAppDelegate application:didFinishLaunchingWithOptions:] + 112
11 UIKit 0x002cc6a7 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
12 UIKit 0x002ceb30 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 346
13 UIKit 0x002d8b6c -[UIApplication handleEvent:withNewEvent:] + 1958
14 UIKit 0x002d12bc -[UIApplication sendEvent:] + 71
15 UIKit 0x002d613f _UIApplicationHandleEvent + 7672
16 GraphicsServices 0x02f4b81e PurpleEventCallback + 1578
17 CoreFoundation 0x0264cff4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
18 CoreFoundation 0x025ad807 __CFRunLoopDoSource1 + 215
19 CoreFoundation 0x025aaa93 __CFRunLoopRun + 979
20 CoreFoundation 0x025aa350 CFRunLoopRunSpecific + 208
21 CoreFoundation 0x025aa271 CFRunLoopRunInMode + 97
22 UIKit 0x002ce3ed -[UIApplication _run] + 625
23 UIKit 0x002da272 UIApplicationMain + 1160
24 TestCustomFileFormat 0x000022e4 main + 102
25 TestCustomFileFormat 0x00002275 start + 53
)
terminate called after throwing an instance of 'NSException'
In response, I tried conforming to NSCoding, used NSKeyedArchiver to create an NSMutableData representation of the class instance and called [data yajl_JSON], but that didn't work either.
I know I'm missing something simple, but I'm too stupid to figure it out.

You’re doing it the wrong way around. To create a JSON string from an object you use yajl_JSONString. yail_JSON is there to take a string (or a NSData object or something that can be archived) and parse that into objects.

Related

Issues with playing Audio (mp3) on Xcode

I have the following problem on my application. When I press the Play button, the mp3 starts playing and also terminates the application.
SongDetailsViewController.h
#import <AVFoundation/AVFoundation.h>
#import <UIKit/UIKit.h>
#interface SongDetailsViewController : UIViewController <AVAudioPlayerDelegate> {
AVAudioPlayer *player;
NSString *songID;
NSString *species;
}
- (void) dismissModal:(id)sender;
- (IBAction) playCall:(id)sender;
- (IBAction) pauseCall:(id)sender;
- (IBAction) stopCall:(id)sender;
#property (nonatomic, retain) AVAudioPlayer *player;
#property (nonatomic, copy) NSString *songID;
#property (nonatomic, copy) NSString *species;
#end
And SongDetailsViewController.m
- (IBAction) pauseCall:(id)sender{
[player pause];
}
- (IBAction) stopCall:(id)sender
{
[player stop];
}
- (IBAction) playCall:(id)sender{
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString *songPath = [documentsDir stringByAppendingPathComponent:#"songs"];
NSString *mySongPath = [songPath stringByAppendingPathComponent:[songID stringByAppendingString:#".mp3"]];
NSURL *file = [[NSURL alloc] initFileURLWithPath:mySongPath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:nil];
player.delegate=self;
[player prepareToPlay];
[player play];
}
Error Stack.
2011-12-29 20:04:40.508 Bird Call Player[6266:307] -[SongDetailsViewController playNote:]: unrecognized selector sent to instance 0x1bcdb0
2011-12-29 20:04:40.531 Bird Call Player[6266:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SongDetailsViewController playNote:]: unrecognized selector sent to instance 0x1bcdb0'
*** Call stack at first throw:
(
0 CoreFoundation 0x344aaed3 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x33975811 objc_exception_throw + 24
2 CoreFoundation 0x344ac683 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102
3 CoreFoundation 0x344541d9 ___forwarding___ + 508
4 CoreFoundation 0x34453f90 _CF_forwarding_prep_0 + 48
5 CoreFoundation 0x34452719 -[NSObject(NSObject) performSelector:withObject:withObject:] + 24
6 UIKit 0x31b30141 -[UIApplication sendAction:to:from:forEvent:] + 84
7 UIKit 0x31b300e1 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32
8 UIKit 0x31b300b3 -[UIControl sendAction:to:forEvent:] + 38
9 UIKit 0x31b2fe05 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 356
10 UIKit 0x31b30453 -[UIControl touchesEnded:withEvent:] + 342
11 UIKit 0x31b2eddd -[UIWindow _sendTouchesForEvent:] + 368
12 UIKit 0x31b2e757 -[UIWindow sendEvent:] + 262
13 UIKit 0x31b299ff -[UIApplication sendEvent:] + 298
14 UIKit 0x31b29337 _UIApplicationHandleEvent + 5110
15 GraphicsServices 0x3026c04b PurpleEventCallback + 666
16 CoreFoundation 0x3443fce3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
17 CoreFoundation 0x3443fca7 __CFRunLoopDoSource1 + 166
18 CoreFoundation 0x3443256d __CFRunLoopRun + 520
19 CoreFoundation 0x34432277 CFRunLoopRunSpecific + 230
20 CoreFoundation 0x3443217f CFRunLoopRunInMode + 58
21 GraphicsServices 0x3026b5f3 GSEventRunModal + 114
22 GraphicsServices 0x3026b69f GSEventRun + 62
23 UIKit 0x31ad0123 -[UIApplication _run] + 402
24 UIKit 0x31ace12f UIApplicationMain + 670
25 Bird Call Player 0x000026cb main + 122
26 Bird Call Player 0x00002114 start + 40
)
terminate called after throwing an instance of 'NSException'
If I move the code inside the playCall into the initWithNibName it works fine. Can someone help me to figure out what is the mistake I have done?
Thanking you in advance
reason: '-[SongDetailsViewController playNote:]: unrecognized selector sent to instance 0x1bcdb0'
in xib did you set your playCall IBAction to your button play or there is another action name?

NSEntityDescription error while fetching the core data

here is my function for fetching core data
- (void)fetchRecords {
// Define our table/entity to use
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Fugitive" inManagedObjectContext:managedObjectContext];
// Setup the fetch request
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
// Define how we will sort the records
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
// Fetch the records and handle an error
NSError *error;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (!mutableFetchResults) {
NSLog(#"Error in Fetching Result");
// Handle the error.
// This is a serious error and should advise the user to restart the application
}
// Save our fetched data to an array
[self setFugitiveArray: mutableFetchResults];
[mutableFetchResults release];
[request release];
}
i got following error while running the program 'Program received signal: "SIGABRT"'
iBountyHunter[1013:207] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Fugitive''
*** Call stack at first throw:
(
0 CoreFoundation 0x011005a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x01254313 objc_exception_throw + 44
2 CoreData 0x00e2aebb +[NSEntityDescription entityForName:inManagedObjectContext:] + 187
3 iBountyHunter 0x000030e6 -[FugitiveListViewController fetchRecords] + 86
4 iBountyHunter 0x00003411 -[FugitiveListViewController viewDidLoad] + 289
5 UIKit 0x00375f26 -[UINib instantiateWithOwner:options:] + 1556
6 UIKit 0x00377ab7 -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 168
7 UIKit 0x0017d17a -[UIApplication _loadMainNibFile] + 172
8 UIKit 0x0017dcf4 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 291
9 UIKit 0x00188617 -[UIApplication handleEvent:withNewEvent:] + 1533
10 UIKit 0x00180abf -[UIApplication sendEvent:] + 71
11 UIKit 0x00185f2e _UIApplicationHandleEvent + 7576
12 GraphicsServices 0x01c48992 PurpleEventCallback + 1550
13 CoreFoundation 0x010e1944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
14 CoreFoundation 0x01041cf7 __CFRunLoopDoSource1 + 215
15 CoreFoundation 0x0103ef83 __CFRunLoopRun + 979
16 CoreFoundation 0x0103e840 CFRunLoopRunSpecific + 208
17 CoreFoundation 0x0103e761 CFRunLoopRunInMode + 97
18 UIKit 0x0017d7d2 -[UIApplication _run] + 623
19 UIKit 0x00189c93 UIApplicationMain + 1160
20 iBountyHunter 0x00002519 main + 121
21 iBountyHunter 0x00002495 start + 53
)
terminate called after throwing an instance of 'NSException'
if you have declare in app delegate then you should check it like :
if (managedObjectContext == nil)
{
managedObjectContext = [(YourAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(#" %#", managedObjectContext);
}

NSInternalInconsistencyException with NSUserDefaults when using method setValue: forPath

My code is as follows:
NSMutableDictionary *configure = [[NSUserDefaults standardUserDefaults] objectForKey:#"configure"];
if (!configure){
configure = [NSMutableDictionary dictionary];
[configure setValue:[NSMutableDictionary dictionary] forKeyPath:#"select"] ;
[configure setValue:[NSMutableDictionary dictionary] forKeyPath:#"select.around"];
[configure setValue: #"All" forKeyPath:#"select.around.name"];
[[NSUserDefaults standardUserDefaults] setObject:configure forKey:#"configure"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
NSString *keyPath = #"configure.select.around";
NSMutableDictionary *aroundConfigure = [[[NSUserDefaults standardUserDefaults] valueForKeyPath:keyPath] mutableCopy];
[aroundConfigure setObject:#"" forKey:#"name"];
[[NSUserDefaults standardUserDefaults] setValue:aroundConfigure forKeyPath:keyPath];
It's crashing every time with the error below:
** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'
*** Call stack at first throw:
(
0 CoreFoundation 0x00daebe9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f035c2 objc_exception_throw + 47
2 CoreFoundation 0x00d67628 +[NSException raise:format:arguments:] + 136
3 CoreFoundation 0x00d6759a +[NSException raise:format:] + 58
4 CoreFoundation 0x00dad401 -[__NSCFDictionary setObject:forKey:] + 209
5 Foundation 0x0004b34d -[NSObject(NSKeyValueCoding) setValue:forKeyPath:] + 399
6 Foundation 0x0004b34d -[NSObject(NSKeyValueCoding) setValue:forKeyPath:] + 399
7 Untitled 0x00002429 -[UntitledAppDelegate application:didFinishLaunchingWithOptions:] + 774
8 UIKit 0x002b81fa -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
9 UIKit 0x002ba55e -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 439
10 UIKit 0x002c4db2 -[UIApplication handleEvent:withNewEvent:] + 1533
11 UIKit 0x002bd202 -[UIApplication sendEvent:] + 71
12 UIKit 0x002c2732 _UIApplicationHandleEvent + 7576
13 GraphicsServices 0x016e4a36 PurpleEventCallback + 1550
14 CoreFoundation 0x00d90064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
15 CoreFoundation 0x00cf06f7 __CFRunLoopDoSource1 + 215
16 CoreFoundation 0x00ced983 __CFRunLoopRun + 979
17 CoreFoundation 0x00ced240 CFRunLoopRunSpecific + 208
18 CoreFoundation 0x00ced161 CFRunLoopRunInMode + 97
19 UIKit 0x002b9fa8 -[UIApplication _run] + 636
20 UIKit 0x002c642e UIApplicationMain + 1160
21 Untitled 0x00002100 main + 102
22 Untitled 0x00002091 start + 53
)
terminate called after throwing an instance of 'NSException'
I know that setObject:forKey: should used with a mutable dictonary . Is there any problem using KVO with NSUserDefaults? By the way, the platform I use is iPhone.
Your code isn't doing what you think it is doing:
NSMutableDictionary *configure = [[NSUserDefaults standardUserDefaults] objectForKey:#"configure"];
This sets configure to be the value of your standard defaults to the value of the key configure
configure = [NSMutableDictionary dictionary];
This sets configure to a new, empty dictionary, not the one you got from User defaults
[configure setValue:[NSMutableDictionary dictionary] forKeyPath:#"select"] ;
You now put an empty dictionary as the value for the key select
[configure setValue:[NSMutableDictionary dictionary] forKeyPath:#"select.around"];
You are adding another empty dictionary for this key path
[configure setValue: #"All" forKeyPath:#"select.around.name"];
And you are setting a string value for this key path
[[NSUserDefaults standardUserDefaults] setObject:configure forKey:#"configure"];
You are now putting this odd dictionary into NSUserDefaults
[[NSUserDefaults standardUserDefaults] synchronize];
NSString *keyPath = #"configure.select.around";
NSMutableDictionary *aroundConfigure = [[[NSUserDefaults standardUserDefaults] valueForKeyPath:keyPath] mutableCopy];
This is just an empty mutable dictionary
[aroundConfigure setObject:#"" forKey:#"name"];
You are setting an empty string for some key in this dictionary
[[NSUserDefaults standardUserDefaults] setValue:aroundConfigure forKeyPath:keyPath];
And then you set this odd dictionary into the the user defaults.
Which is all very confusing.
What is it that you are trying to do?
Edited to add
There's no point providing code if you've "simplified" it we can't see what it's supposed to do.
Your app is crashing because you are trying to change a key value pair of a NSDictionary which is immutable instead of a NSMutableDictionary. See line 6 of your trace.
Since you've provided "simplified" code - I don't know where you are doing this.
Today i also faced this problem because i am making data in dictionary like this
NSMutableDictionary *Dic =[myMutableAry objectAtIndex:0];
after getting data when i am updating my dic value then getting crash
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary
setObject:forKey:]: mutating method sent to immutable object'
Then i did got solution after a lot of research , so just do one thing
NSMutableDictionary *Dic = [NSMutableDictionary dictionaryWithDictionary:[myMutableAry objectAtIndex:0]];
The way you have used the NSUserDefaults is wrong, NSUserDefaults return a non mutable dictionary. That is the cause of this issue. Therefore, you have to request a mutable object explicitly from NSUserDefaults. Please use the code line below.
NSMutableDictionary *configure = [[[NSUserDefaults standardUserDefaults] objectForKey:#"configure"]mutableCopy];
This work with me.
Thanks Good luck :)

Accelerometer - Crashing after shaken - Cocoa Touch

Hello
I'm trying to have it, so once the user shakes the device. I want a sound to play. However once I shake the device it crashes, this is the code which I have used
- (BOOL)canBecomeFirstResponder
{
return YES;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if(motion == UIEventSubtypeMotionShake)
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"sound" ofType:#"wav"];
if (theAudio) [theAudio release];
NSError *error = nil;
theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
if (error)
NSLog(#"%#",[error localizedDescription]);
theAudio.delegate = self;
[theAudio play];
}
}
And this is the crash report
2011-04-19 19:25:44.337 iApp[314:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL initFileURLWithPath:]: nil string parameter'
*** Call stack at first throw:
(
0 CoreFoundation 0x00fc3be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00db85c2 objc_exception_throw + 47
2 CoreFoundation 0x00f7c628 +[NSException raise:format:arguments:] + 136
3 CoreFoundation 0x00f7c59a +[NSException raise:format:] + 58
4 Foundation 0x00055b12 -[NSURL(NSURL) initFileURLWithPath:] + 90
5 Foundation 0x00055aa0 +[NSURL(NSURL) fileURLWithPath:] + 72
6 iApp 0x0000305d -[AppViewController motionEnded:withEvent:] + 256
7 UIKit 0x002dc07c -[UIWindow sendEvent:] + 350
8 UIKit 0x002bf37a -[UIApplication sendEvent:] + 447
9 UIKit 0x002c311b _UIApplicationHandleEvent + 1921
10 GraphicsServices 0x017daa36 PurpleEventCallback + 1550
11 CoreFoundation 0x00fa5064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
12 CoreFoundation 0x00f056f7 __CFRunLoopDoSource1 + 215
13 CoreFoundation 0x00f02983 __CFRunLoopRun + 979
14 CoreFoundation 0x00f02240 CFRunLoopRunSpecific + 208
15 CoreFoundation 0x00f02161 CFRunLoopRunInMode + 97
16 GraphicsServices 0x017d9268 GSEventRunModal + 217
17 GraphicsServices 0x017d932d GSEventRun + 115
18 UIKit 0x002c842e UIApplicationMain + 1160
19 iApp 0x0000295c main + 102
20 iApp 0x000028ed start + 53
)
terminate called after throwing an instance of 'NSException'
Given the crash report reason:
reason: '*** -[NSURL initFileURLWithPath:]: nil string parameter'
along with the last executed line in your app's code:
6 iApp 0x0000305d -[AppViewController motionEnded:withEvent:] + 256
I would think that your sound.wav file is missing:
NSString *path = [[NSBundle mainBundle] pathForResource:#"sound" ofType:#"wav"];
I suggest your make sure:
the sound.wav file is in your project
is case sensitively spelled "sound.wav"
Hope this helps.

Save and Retrieve of an UIImage on CoreData

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 http://www.freeimagehosting.net/uploads/7c286931cc.png
I spent a lot of time with this. Please help me out!
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.
Here's the proper solution that works very well.
1) Storing UIImage with Core Data:
NSData* coreDataImage = [NSData dataWithData:UIImagePNGRepresentation(delegate.dancePhoto)];
Make sure that "coreDataImage" is of type NSData. You have to set type to "Binary data" for "coreDataImage" in your model.
2) Retrieving UIImage from Core Data:
UIImage* image = [UIImage imageWithData:selectedDance.danceImage];
That's all there's to it, works great.
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.
The Solution I used was to create the category bellow. You just need it in your project for it to work. Using this storing images works just like you where storing an 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
This sample code has example how to store UIImage in Core Data:
https://developer.apple.com/library/ios/#samplecode/PhotoLocations/Introduction/Intro.html