accessing the setMethod of a #property in ios - ios

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)

Related

[NSManagedObject setSwitchState:]: unrecognized selector sent in Objective-C

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...

-[__NSArrayI objectForKeyedSubscript:]: unrecognized selector sent to instance IN xcode6 objective-c ios

I am trying to learn objective-c, and came across some crash I couldn't resolve.
I believe it's one of the basic problems, but I am new here and got lost in the middle.
I have :
ModelViewController.h
ModelViewController.m
Schedule.h
Schedule.m
in ModelViewController.h
#import <UIKit/UIKit.h>
#interface FetchScheduleVC : UIViewController
#property (copy, nonatomic) NSMutableArray *myMutableArray;
#end
in ModelViewController.m
#import "ModelViewController.h"
#import "Schedule.h"
#implementation Model
- (void)viewDidLoad {
[super viewDidLoad];
for(int i=0; i < 3; i++){
[_myMutableArray addObjects: [NSNumber numberWithInt: i]
}
}
- (IBAction)saveBtn:(UIButton *)sender {
Schedule *newSchedule = [[Schedule alloc]init];
[newSchedule createClassFromArray: _myMutableArray];
}
#end
in Schedule.h
#import <Foundation/Foundation.h>
#interface Schedule : NSObject
#property (strong, nonatomic) NSMutableArray *classArray;
-(void) createClassFromArray: (NSArray *) selectedArr;
#end
in Schedule.m
#import "Schedule.h"
#implementation Schedule
-(void) createClassFromArray: (NSArray *) selectedArr {
for(NSNumber *i in selectedArr){
NSLog(#"number in array is : %#", i);
}
}
#end
I simplified my codes a little, but the basic flow is the same.
When I run this, and click a button to call - (IBAction)saveBtn:(UIButton *)sender, I get:
-[__NSArrayI objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7fcb61d2fd10
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7fcb61d2fd10'
Anything wrong doings in sending NSArray through Method up here?
I can only tell you what's happening in your code, not where it's happening, as you've not posted the offending code.
The objectForKeyedSubscript method is called for NSDictionary subscripting, for example:
NSDictionary *dict = #{ #"key" : #"value" };
NSString *value = dict[#"key"]; // HERE
so it looks like you are doing something like this:
for(int i=0; i < 3; i++){
[_myMutableArray addObjects: [NSNumber numberWithInt: i]
}
NSNumber *num = _myMutableArray[#"3"]; // !!!!
One more thing I can tell you, it's not to do with uninitialized array as Objective-C simply ignores attempts to dereference nil objects and this exception has gone further than that.
As you have declared myMutableArray with copy semantic as-
#property (copy, nonatomic) NSMutableArray *myMutableArray;
this will sends a copy message to the array, which results in an immutable copy.
So, to use above semantics on NSMutableArray you need to override the "setter" method as -
- (void)setArray:(NSArray *)newArray
{
if ( array != newArray )
{
[array release];
array = [newArray mutableCopy];
}
}
the above setter method just assign the reference of mutable copy of the newArray to the array, which help you to mutate the objects and thus avoiding the error.
In the codes above, I forgot to include
_myMutableArray = [[NSMutableArray alloc] init];
although i had that in my actual code.
the problem was very dumb. Sorry for this misleading question. Hope you just ignore this question cuz it's due to such a careless mistake.
In my actual code, I had duplicate variable names like this:
in Schedule.h
#import <Foundation/Foundation.h>
#interface Schedule : NSObject
#property (strong, nonatomic) NSMutableArray *selectedArr;
-(void) createClassFromArray: (NSArray *) selectedArr;
#end
..very.. careless mistake.

MOTIS Object Mapping, With NSDictionary with values NSArray how can I specify type of array elements?

I have the json
{"Types":{
"food":[{"cve":"1","description":"Pizza"},{"cve":"2","description":"Restaurant"},{"cve":"3","description":"Cafe"}],
"Health":[{"cve":"3","description":"Pharmacy"},{"cve":"4","description":"Hospital"}]
} }
Types.h
#import <Foundation/Foundation.h>
#interface Types: NSObject
#property (nonatomic, copy) NSDictionary *types;
#end
Types.m
#import "Types.h"
#import <Motis/Motis.h>
#import "SubTipo.h"
#implementation Types
+ (NSDictionary*)mts_mapping
{
return #{#"types": mts_key(types),};
}
#end
Subtype.h
#import <Foundation/Foundation.h>
#interface Subtype: NSObject
#property (nonatomic, assign) int cve;
#property (nonatomic, copy) NSString *description;
#end
Subtype.m
#import "Subtype.h"
#import <Motis/Motis.h>
#implementation Subtype
+ (NSDictionary*)mts_mapping
{
return #{#"cve": mts_key(cve),
#"description": mts_key(description),
};
}
#end
I deserialize with
Types * values=[[Types alloc]init];
NSDictionary * jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
[values mts_setValuesForKeysWithDictionary:jsonObject ];
I get NSDictionary with NSArray of NSDictionary
but I need NSDictionary with NSArray of Subtypes
I try with
+ (NSDictionary*)mts_arrayClassMapping
{
return #{mts_key(types): Subtype.class};
}
but wasn't successful
How can I get these with Motis
As far as I see, your Types object is not properly defined. If you have an attribute of type NSDictionary* and the JSON received is a Dictionary, Motis won't perform any automatic conversion as the types already match (you are receiving a dictionary and your attribute is of type NSDictionary).
Therefore, you must implement your Type object following your JSON structure. This means that your Type object must have two properties of type array, one for food and one for health. Then, using the method +mts_arrayClassMapping you can specify the content type of the arrays to Subtype.
Here the implementation:
// ***** Type.h file ***** //
#interface Type: NSObject
#property (nonatomic, strong) NSArray *food;
#property (nonatomic, strong) NSArray *health;
#end
// ***** Type.m file ***** //
#implementation Type
+ (NSDictionary*)mts_mapping
{
return #{#"food": mts_key(food),
#"Health": mts_key(health),
};
}
+ (NSDictionary*)mts_arrayClassMapping
{
return #{mts_key(food): Subtype.class,
mts_key(health): Subtype.class,
};
}
#end
Regarding the implementation of Subtype, yours is already correct. However, you should not use the property name description as it is already being used by NSObject:
// ***** Subtype.h file ***** //
#interface Subtype: NSObject
#property (nonatomic, assign) NSInteger cve;
#property (nonatomic, copy) NSString *theDescription;
#end
// ***** Subtypes.m file ***** //
#implementation Subtype
+ (NSDictionary*)mts_mapping
{
return #{#"cve": mts_key(cve),
#"description": mts_key(theDescription),
};
}
#end
Finally, as you list above, you can map your JSON, but first you will have to extract the "dictionary" for key Types, which you will map to your "Type" model object.
// Get the json data
NSDictionary * jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
// Extract the JSON dictionary of types.
NSDictionary *jsonType = [jsonObject objectForKey:#"Types"];
// Create a Type object
Type *type = [[Type alloc] init];
// Map JSON contents to the type object with Motis
[type mts_setValuesForKeysWithDictionary:jsonType];
Hoping this fixes your issue.

No visible #interface for 'NSMutableDictionary' declares the selector 'addObjects:forKey'

My code gives an error saying
No visible interface for 'NSMutableDictionary' declares the selector 'addObjects:forKey:'
.h
#interface ViewController : UIViewController{
NSMutableDictionary *credtialsDictionary;
}
-(IBAction)registerlogin;
#end
.m
#implementation ViewController
-(IBAction)registerlogin{
[credtialsDictionary addObjects:passwordFieldregister.text forKey:usernameFieldregister];
}
#end
I can't figure out why this IBAction isn't letting me add objects to the NSMutableDictionary
Because there is no instance method addObjects:forKey: in an NSMutableDictionary.
The method you are looking for is setObject:forKey:. (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSMutableDictionary_Class/Reference/Reference.html)
If you say why you thought the method should be addObjects:forKey: I can help you in a more generic way. But in general you want to look in Apple's documentation (like in the link above, generally just google the class name), or in look in the headers, in Xcode you can press Cmd-Shit-O and then type the name of a class and you can open the header from there.
A clue that you've got the wrong method in this case is that addObjects is plural (and forKey isn't) and you're only trying to add one object.
Perhaps because the method name is setObject:forKey:
There is no such method addObjects:forKey:, and that wouldn't make sense as it's not meaningful to have multiple objects correspond to one key. But if you want to add multiple objects for keys in one call, it's easy enough to add something via a category if you're so inclined. An example:
#import <Foundation/Foundation.h>
#interface NSMutableDictionary (CBVAdditions)
- (void)cbvSetObjects:(NSArray *)objects forKeys:(NSArray *)keys;
#end
#implementation NSMutableDictionary (CBVAdditions)
- (void)cbvSetObjects:(NSArray *)objects forKeys:(NSArray *)keys
{
NSDictionary *tempDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
[self addEntriesFromDictionary:tempDictionary];
}
#end
int main(int argc, char *argv[]) {
#autoreleasepool {
NSMutableDictionary *md = [NSMutableDictionary dictionary];
[md cbvSetObjects:#[#"obj1", #"obj2"] forKeys:#[#"key1", #"key2"]];
NSLog(#"md = %#", md);
}
}
Output:
2014-05-07 15:51:03.056 Untitled[38754:507] md = {
key1 = obj1;
key2 = obj2; }

Pass Array to NSObject Class

I'm new to iphone app development and I'm stuck on this problem I'm having with the app I'm trying to develop.
I have a datacontroller for populating a tableview. I created it using this tutorial:
About Creating Your Second iOS App
I'm trying to pass an array from one of my viewcontrollers that was created from a JSON response.
Here is some code from my viewcontroller.h that needs to pass the array:
#interface ViewController : UIViewController
#property (nonatomic, retain) DataController *Data;
#property (nonatomic, retain) NSMutableArray *array;
#end
viewcontroller.m:
#import "DataController.h"
[Data setMasterList: self.array];
DataController.h:
#interface DataController : NSObject
#property (nonatomic, strong) NSMutableArray *masterList;
- (void)setMasterList:(NSMutableArray *)newList;
#end
DataController.m
#import "LoginViewController.h"
- (void)setMasterList:(NSMutableArray *)newList {
if (_masterList != newList) {
_masterList = [newList mutableCopy];
NSLog("List: %#", newList);
}
}
The NSLog message never shows up in the console and the array is nil.
Any help is appreciated.
Thanks.
EDIT:
Here's the updated viewcontroller.m:
Data = [[DataController alloc] init];
[Data setMasterList: self.array];
The datacontroller.m:
- (void)setMasterList:(NSMutableArray *)newList {
if (_masterList != newList) {
_masterList = [newList mutableCopy];
NSLog("List: %#", self.masterList);
}
}
- (NSUInteger)countOfList {
NSLog("List: %#", self.masterList);
return [self.masterList count];
}
The first nslog inside setMasterList returns the correct array values, but the second nslog inside countOfList returns null. The list always returns null anywhere outside of setMasterList. Is it because I'm creating a new instance of the DataController? If so, how else could I pass the array to the datacontroller.
As in first comment Till have suggested, Data must be initialized before calling setMasterList. Such As:
Data = [[DataController alloc] init];
[Data setMasterList: self.array];

Resources