after checking all the answers of "Unrecognised selector sent" questions such as unrecognized selector sent to instance, and Unrecognized selector sent to instance? did not satisfy my situation so for that here is my full scenario:
Description:
in my app there exist a settings View which contain a UISwitch either to add all his reservation to the phone calendar or not.
so I need to save the choice of the user inside CoreData to add reservations to calendar or not i.e the state of the UISwitch.
initially when the app start for the first time the UISwitch will be ON and his state will be saved inside the CoreData with fixed ID 1 because I don`t want to add many Objects I need to keep only one object and when the user change the value of the UISwitch the app should update the object with new state I try this solution How to update existing object in Core Data? also I got an error
Full Code:
SwitchStateEntity.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface switchState : NSManagedObject
#property(strong,nonatomic) NSNumber *switchId;
#property (nonatomic,strong) NSNumber *switchState;
#property (nonatomic,strong) NSNumber *showReminderAlert;
#end
SwitchStateEntity.m
#import "switchState.h"
#implementation switchState
#dynamic switchId;
#dynamic switchState;
#dynamic showReminderAlert;
#end
SettingsViewController.h
#import <UIKit/UIKit.h>
#import "MakeReservationViewController.h"
#interface SettingsViewController : UIViewController
#property (weak, nonatomic) IBOutlet UISwitch *isAdedToCalendarOrNot;
#property (nonatomic) Boolean isSwitchOnOrOf;
#property (nonatomic,strong) NSString *savedEventId;
#end
SettingsViewController.m
- (IBAction)DoneButtonPressed:(id)sender {
// check the state of the switch //
// save this state //
NSError *error;
CoreData *coreDataStack = [CoreData defaultStack];
NSArray *fetchedObjects;
NSFetchRequest *fetchRequest;
NSEntityDescription *entity;
// setting up the variable needed //
fetchRequest = [[NSFetchRequest alloc] init];
entity = [NSEntityDescription entityForName:#"SwitchState" inManagedObjectContext:coreDataStack.managedObjectContext];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"remindMeSwitchId== %d", 1]];
[fetchRequest setEntity:entity];
fetchedObjects = [coreDataStack.managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSLog(#"%#",fetchedObjects);
for( NSEntityDescription *name in fetchedObjects)
{
NSLog(#"Switch Id is: %#",[name valueForKey:#"remindMeSwitchId"]);
NSLog(#"Switch State is: %#",[name valueForKey:#"remindMeSwitchState"]);
SwitchStateEntity *h = [ fetchedObjects firstObject];
[h setSwitchState:[NSNumber numberWithBool:self.isSwitchOnOrOf]];
// after this statement i go into Unrecognised selector had been sent//
[coreDataStack saveContext];
NSLog(#"Switch Id is: %#",[name valueForKey:#"remindMeSwitchId"]);
NSLog(#"Switch State is: %#",[name valueForKey:#"remindMeSwitchState"]);
}
[self dismissSelf];
}
- (IBAction)isAdedToCalendarValueChanged:(id)sender {
if ([self.isAdedToCalendarOrNot isOn]) {
self.isSwitchOnOrOf = YES;
}
else
{
self.isSwitchOnOrOf = NO;
}
}
and for the exception that the app goes through:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSManagedObject setSwitchState:]: unrecognised selector sent to instance 0x7fb6f3411d20'
and for my xcdatamodel:
SwitchStateEntity *h = [ fetchedObjects firstObject];
//try this code
NSLog(#"it should not be nil = %#",self.isSwitchOnOrOf);
[h setSwitchState:[NSNumber numberWithBool:self.isSwitchOnOrOf]];
Update Code in Such File
SwitchStateEntity.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface SwitchStateEntity : NSManagedObject
#property(strong,nonatomic) NSNumber *switchId;
#property (nonatomic,strong) NSNumber *switchState;
#property (nonatomic,strong) NSNumber *showReminderAlert;
#end
SwitchStateEntity.m
#import "SwitchStateEntity.h"
#implementation SwitchStateEntity
#dynamic switchId;
#dynamic switchState;
#dynamic showReminderAlert;
#end
Also Update Entity name and class name in .xcdatamodeld file
Do a NSLog("%#", NSStringFromClass(h.class)) to see what kind of class the SwitchState object really is. Chances are you've incorrectly configured something in your Core Data Model file.
Also, seriously, all your class names should be UpperCaseWords...
Related
after many hour of tutorials and googling i knew that when we define a property inside the header file the compiler automatically generate the setters and getters here is an example:
"example.h"
#property(strong,nonatomic) NSNumber *test;
example.m
[self.test setTest [#"3"]];
so what i want is to access this method to check the method declaration and here is the reason that i want
Full Scenario
#interface exampleController ()
{
int example;
}
// here is a instance variable used to save a value while the app running i am getting this value from a dictionary and then save the value of the example variable to the core data
here is the entity class
exampleEntity.h
#property(strong,nonatomic) NSNumber *example;
exampleEntity.m
#dynamic example;
// since the instance variable is int we need to cast it to NSNumber so i follow this link
[entry setExample : [NSNumber numberWithInt:example]];
Finally after running this code i go into this exception:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException'
Full Code
#import "viewController.h"
#interface viewController ()
{
int example;
}
- (void)viewDidLoad {
gettingTheExampleValueFromDictionary();
}
-(void)gettingTheExampleValueFromDictionary()
{
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:requestHandler options:0 error:&jsonParsingError];
example = [[dictionary objectForKey:#"exampleId"] intValue];
}
- (IBAction)doneButton:(id)sender {
[self insertDataToCoreData];
[self dismissSelf];
}
-(void)insertDataToCoreData {
CoreData *coreDataStack = [CoreData defaultStack];
ExampleEntity *entry = [NSEntityDescription insertNewObjectForEntityForName:
#"ExampleEntity" inManagedObjectContext:coreDataStack.managedObjectContext];
[entry setExample :[NSNumber numberWithInt:example]];
// here we go into the error //
[coreDataStack saveContext];
}
#end
// and if you ask me for entity class here is:
#import <Foundation/Foundation.h>
#interface ReservationEntity : NSObject
#property (nonatomic,strong) NSNumber *example;
#end
#import "exampleEntity.h"
#implementation exampleEntity
#dynamic example;
#end
// and if you ask me for core data here is the pic needed //
// the configuration of xcdatamodel
In your case you should change:
#dynamic example;
to
#synthesize example;
or just delete the line of code #dynamic example.
Because #synthesize generates the getter&setter for the property, while #dynamic means the getter&setter are created in runtime(e.g. NSManagedObject's subclasses)
I have a Product model with the header:
#interface Product : RLMObject <NSCopying,NSCoding>
{
}
#property (nonatomic, strong) NSString *title;
#property (nonatomic, strong) NSString *thumbnailURL;
#property (nonatomic, strong) UIImage *thumbnail;
-(id)initWithInfo:(NSDictionary*)dictionary;
-(UIImage*)getThumbnail;
and implementation:
#implementation Product
-(id)initWithInfo:(NSDictionary*)dictionary
{
self = [self init];
if (self) {
_title = dictionary[#"title"];
_thumbnailURL = dictionary[#"thumbnailURL"];
_thumbnail = [self getThumbnail];
}
return self;
}
-(UIImage*)getThumbnail
{
if (_thumbnail) {
return _thumbnail;
}
//load image from cache
return [self loadImageFromCache];
}
Now, when I try to create a Product object and insert it into Realm, I always get the exception
[RLMStandalone_Product getThumbnail]: unrecognized selector sent to instance 0xcd848f0'
Now, I remove _thumbnail = [self getThumbnail]; and it works fine. But then I get another exception
[RLMStandalone_Product title]: unrecognized selector sent to instance 0xd06d5f0'
when I reload my view. I have created my Product object in the main thread, so it should be fine to using its property and method, isn't it?
Any advice will be appreciated!
Because Realm object properties are backed by the database rather than in-memory ivars, accessing those properties' ivars is not supported. We're currently clarifying our docs to convey this:
Please note that you can only use an object on the thread from which is was created or obtained, ivars shouldn't be accessed directly for any persisted properties, and that getters and setters for persisted properties cannot be overridden.
So to work with Realm, your model should look like this:
#interface Product : RLMObject
#property NSString *title;
#property NSString *thumbnailURL;
#property (nonatomic, strong) UIImage *thumbnail;
#end
#implementation Product
-(UIImage*)thumbnail
{
if (!_thumbnail) {
_thumbnail = [self loadImageFromCache];
}
return _thumbnail;
}
-(UIImage*)loadImageFromCache
{
// Load image from cache
return nil;
}
+(NSArray*)ignoredProperties
{
// Must ignore thumbnail because Realm can't persist UIImage properties
return #[#"thumbnail"];
}
#end
And usage of this model could look like this:
[[RLMRealm defaultRealm] transactionWithBlock:^{
// createInDefaultRealmWithObject: will populate object keypaths from NSDictionary keys and values
// i.e. title and thumbnailURL
[Product createInDefaultRealmWithObject:#{#"title": #"a", #"thumbnailURL": #"http://example.com/image.jpg"}];
}];
NSLog(#"first product's image: %#", [(Product *)[[Product allObjects] firstObject] thumbnail]);
Notice how initWithInfo isn't necessary because RLMObject already has initWithObject: and createInDefaultRealmWithObject: already do this.
I am having two classes or objects: User and Medicine. Here is my User class:
#interface User : NSManagedObject
#property (nonatomic, retain) NSString * name;
#property (nonatomic, retain) NSSet *medicine;
#end
#interface User (CoreDataGeneratedAccessors)
- (void)addMedicineObject:(Medicine *)value;
- (void)removeMedicineObject:(Medicine *)value;
- (void)addMedicine:(NSSet *)values;
- (void)removeMedicine:(NSSet *)values;
#end
and then the Medicine class
#interface Medicine : NSManagedObject
#property (nonatomic, retain) NSString * medName;
#property (nonatomic, retain) NSString * medType;
#property (nonatomic, retain) Dose *dose;
#property (nonatomic, retain) User *user;
#end
As my interfaces clearly show that user may have multiple medicines. (I am from database background thats why I am interpreting it like this).
When I add new object in User, it is easily done, but when I try to add new Medicine for existing object of user, I feel that my Xcode has a deep wish to shoot me at that time (vice versa).
Now here is the code that describes what I am doing:
Medicine *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
User *user = [NSEntityDescription insertNewObjectForEntityForName:#"User" inManagedObjectContext:self.managedObjectContext];
if(![self checkUser])
{
object.user = user;
[user setName:self.userName];
NSLog(#"%# %#",object, user);
self.detailViewController.detailItem = object;
}
else
{
Medicine *medicine = [NSEntityDescription insertNewObjectForEntityForName:#"Medicine" inManagedObjectContext:self.managedObjectContext];
user = [self getUser:self.userName];
medicine.medName = object.medName;
medicine.medType = object.medType;
[medicine setUser:user];
self.detailViewController.detailItem = medicine;
}
I am having a simple logic: if name entered by user in text field, already exist in DB, then return the User object. Then just add another Medicine record for the same User. Other wise add new User and a Medicine object as well.
but I get error at:
[medicine setUser:user];
I also tried this one: (as I got it in another question like mine)
[user addMedicineObject:medicine];
Now I think that I have to override addMedicineObject method or something else.
Oh I forgot the error. I get this error: (the real villain)
[__NSArrayM managedObjectContext]: unrecognized selector sent to instance 0x8136bf0
Now any suggestion?
It is because you trying to mutate NSSet object. You need to create a mutable copy before you edit it.
I have a Core Data model as follows, where children is a to-many relationship.
.h
#implementation MyEntity
#dynamic name;
#dynamic children;
#end
.m
#interface MyEntity : NSManagedObject
#property (nonatomic) NSString *name;
#property (nonatomic) NSOrderedSet *children;
#end
I then try to set it using:
MYAppDelegate *delegate = (MYAppDelegate *)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *managedObjectContext = [delegate managedObjectContext];
NSEntityDescription *categoryEntity = [NSEntityDescription entityForName:#"MyEntity" inManagedObjectContext:managedObjectContext];
NSManagedObject *newCategory = [[NSManagedObject alloc] initWithEntity:categoryEntity insertIntoManagedObjectContext:managedObjectContext];
[newCategory setValue:key forKey:#"name"];
NSOrderedSet *testSet = [[NSOrderedSet alloc] initWithArray:#[#"This", #"is", #"a", #"test"]];
[newCategory setValue:testSet forKey:#"children"];
}
}
Yet on that last line, I get this error:
NSCFConstantString managedObjectContext]: unrecognized selector sent
to instance 0xe8fa0'
If I change NSOrderedSet to NSSet the compiler complains that it expects an NSOrderedSet.
How can I assign the set to the NSManagedObject?
The problem isn't the NSOrderedSet, its the NSString instances that you put inside the set. These need to be replaces with instances of the entity which is configured in the data model at the destination of the relationship. You can't fill the relationship with the wrong kind of object.
I am having a serious issue within my CoreData database. I have created a One To Many relationship between 2 tables and added a Fetched Property on the Table containing all unique values. All code works as expected within iOS 5 but in iOS 6 I receive the following errror:
2013-02-08 15:15:49.382 ArdsBoroughCouncil[16152:c07] * Terminating
app due to uncaught exception 'NSUnknownKeyException', reason:
'[<_NSObjectID_48_0 0xb25c3b0> valueForUndefinedKey:]: this class is
not key value coding-compliant for the key tour_id.'
* First throw call stack: (0x31c7012 0x24a3e7e 0x324ffb1 0x1c445ed 0x1bb08db 0x1bb088d 0x1bceb17 0x1bfe746 0x21b74bb 0x21b7176 0x21b6e44
0x21b66f4 0x21b2d63 0x21b2a82 0x21b2850 0x21b2625 0x21b1e07 0x21b18f4
0x21b0a6d 0x21ae9c9 0x2201276 0x227b155 0x2201071 0x2880014 0x286fd5f
0x286faa3 0x220103b 0x2200e9e 0x21ae9c9 0x2209dfa 0x22375cf 0x2237a03
0x59de1 0x11c2753 0x11c2a7b 0x11d0590 0x11d85bd 0x11d8eab 0x11d94a3
0x11d9098 0x1534da3 0x1526ad9 0x1526b54 0x24b7705 0x10e2920 0x10e28b8
0x11a3671 0x11a3bcf 0x11a2d38 0x111233f 0x1112552 0x10f03aa 0x10e1cf8
0x34b3df9 0x34b3ad0 0x313cbf5 0x313c962 0x316dbb6 0x316cf44 0x316ce1b
0x34b27e3 0x34b2668 0x10df65c 0x291d 0x2845) libc++abi.dylib:
terminate called throwing an exception
The predicate defined for the Fetched Property is:
($FETCH_SOURCE.tour_id == tour_id) AND ($FETCH_SOURCE != SELF)
I have defined the array to return all receive all values within my Tour class.
Are you aware of any issues with Fetched Properties wihtin iOS 6 ? As I cannot understand this works with no issue in iOS 5 but fails in iOS6.
Please see all other related code below:
The code below is how I am retrieving all records:
- (void)loadRecordsFromCoreData {
[self.managedObjectContext performBlockAndWait:^{
[self.managedObjectContext reset];
NSError *error = nil;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:NSStringFromClass([Tour class]) inManagedObjectContext:self.managedObjectContext];
[request setEntity:entityDescription];
[request setResultType:NSManagedObjectResultType];
[request setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"tour_id" ascending:YES]]];
self.tours = [self.managedObjectContext executeFetchRequest:request error:&error];
}];
The code below shoes the NSManagedObjects I have defined:
-- Tour
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#class TourDetail;
#interface Tour : NSManagedObject
#property (nonatomic, retain) NSNumber * tour_id;
#property (nonatomic, retain) NSString * background_url;
#property (nonatomic, retain) NSString * summary;
#property (nonatomic, retain) NSString * title;
#property (nonatomic, retain) NSSet *tourdetails_tour;
#property (nonatomic, retain) NSArray *tourDetails;
#end
#interface Tour (CoreDataGeneratedAccessors)
- (void)addTourdetails_tourObject:(TourDetail *)value;
- (void)removeTourdetails_tourObject:(TourDetail *)value;
- (void)addTourdetails_tour:(NSSet *)values;
- (void)removeTourdetails_tour:(NSSet *)values;
#end
}
#import "Tour.h"
#import "TourDetail.h"
#implementation Tour
#dynamic tour_id;
#dynamic background_url;
#dynamic summary;
#dynamic title;
#dynamic tourdetails_tour;
#dynamic tourDetails;
#end
-- Tour Detail
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#class Tour;
#interface TourDetail : NSManagedObject
#property (nonatomic, retain) NSNumber * id;
#property (nonatomic, retain) NSNumber * tour_id;
#property (nonatomic, retain) NSNumber * lattitude;
#property (nonatomic, retain) NSNumber * longitude;
#property (nonatomic, retain) NSString * audiofile;
#property (nonatomic, retain) NSString * detail;
#property (nonatomic, retain) NSString * title;
#property (nonatomic, retain) Tour *tour_tourdetails;
#end
#import "TourDetail.h"
#import "Tour.h"
#implementation TourDetail
#dynamic id;
#dynamic tour_id;
#dynamic lattitude;
#dynamic longitude;
#dynamic audiofile;
#dynamic detail;
#dynamic title;
#dynamic tour_tourdetails;
#end
Any advise you can offer would be greatly appreciated :) As well as any examples you may have as to how best to define fetched properties ?
Thanks,
Michael
The code your using here is not clean
- (void)loadRecordsFromCoreData {
[self.managedObjectContext performBlockAndWait:^{
[self.managedObjectContext reset];
NSError *error = nil;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:NSStringFromClass([Tour class]) inManagedObjectContext:self.managedObjectContext];
[request setEntity:entityDescription];
[request setResultType:NSManagedObjectResultType];
[request setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"tour_id" ascending:YES]]];
self.tours = [self.managedObjectContext executeFetchRequest:request error:&error];
}];
In fact, it is a little confusing.
Your calling a method, that calls a managed object context, which further calls itself within a synchronous block, which resets itself for no reason, which sets a property 'self.tours' outside of the block. All very odd. Can you explain why you are doing this?
Try this instead.
+(void)loadRecordsWithCompletion:(void(^)(NSArray *records, NSError *error))completion {
NSManagedObjectContext *context; //Your context
NSError *error;
NSSortDescriptor *sortDesc = [NSSortDescriptor sortDescriptorWithKey:#"attribute" ascending:YES];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"EntityName"];
[request setSortDescriptors:#[sortDesc]];
NSArray *records = [context executeFetchRequest:request
error:&error];
completion(records, error);
}