UISegmentedControl CoreData Binding Error - ios

I keep getting this error when i try to bind a nsobject to a segment control
UserLocation isEqualToString:]: unrecognized selector sent to instance 0x7477a60
2013-01-22 12:44:58.115 Momentum[39936:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UserLocation isEqualToString:]: unrecognized selector sent to instance 0x7477a60'
I have verified that my core data object has data.
NSarray *arrayuserlocation = [[MMIStore defaultStore] loadAllUserLocation];
UISegmentedControl *segControl = [[UISegmentedControl alloc]initWithItems:arrayuserlocation];
[segControl addTarget:self action:#selector(didChangeSegmentControl:) forControlEvents:UIControlEventValueChanged];
[segControl setSegmentedControlStyle:UISegmentedControlStyleBar];
[segControl setTintColor:[UIColor grayColor]];
EDIT
To the answer the question below
- (NSMutableArray *)loadAllUserLocation
{
if (!allItems) {NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *e = [[model entitiesByName] objectForKey:#"UserLocation"];
[request setEntity:e]
NSError *error;
NSArray *result = [context executeFetchRequest:request error:&error];
if (!result) {
[NSException raise:#"Fetch failed"
format:#"Reason: %#", [error localizedDescription]];
}
allItems = [[NSMutableArray alloc] initWithArray:result];
}
return allItems;
It returns an array
I was able to solve my problem by doing the following.
NSArray *arraylocation = [[MMIStore defaultStore] loadAllUserLocation];
NSMutableArray *newarray = [[NSMutableArray alloc] init];
for (UserLocation *user in arraylocation)
{
NSLog(#"%# found", user.locationNm);
[newarray addObject:user.locationNm];
}
And using newarray as the datasource for the segment control.

As I mentioned in comments, the issue is that you are passing userlocation objects instead of NSString or UIImage objects required.
As per the documentation your items array should be "an array of NSString objects (for segment titles) or UIImage objects (for segment images)."
You need to fetch the strings from user location as,
NSarray *arrayuserlocation = [[[MMIStore defaultStore] loadAllUserLocation] valueForKey:#"locationNm"];//use the param name here
This should give you an array of all strings from the array of objects.

The problem is, the arrayuserlocation array should contain NSStrings instead of NSManagedObjects.

The code that's throwing the exception is expecting you to pass it an NSString (this is the object that responds to isEqualToString:). However, you are passing it a UserLocation object. You need to load up arrayuserlocation with strings from the UserLocation object, not just send an array of objects themselves.

Related

-[__NSArrayM objectForKey:]: unrecognized selector sent to instance 0x9d0d720

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[jsonArray removeAllObjects];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
responseData = nil;
NSMutableArray *sdf = [(NSDictionary*)[responseString JSONValue] objectForKey:#"DataTable"];
NSMutableArray * myArray = [[NSMutableArray alloc] init];
NSMutableDictionary * myDict = [[NSMutableDictionary alloc] init];
if (([(NSString*)sdf isEqual: [NSNull null]])) {
// Showing AlertView Here
}else {
for (int i=0; i<[sdf count]; i++) {
myDict=[sdf objectAtIndex:i];
[myArray addObject:[myDict objectForKey:#"RxnCustomerProfile"]];
}
jsonArray=[myArray mutableCopy];
NSMutableDictionary *dict=[jsonArray objectAtIndex:0];
if ([dict count]>1) {
// Showing AlertView Here
}
}
}
Hi Everyone, I have an issue regarding the -[__NSArrayM objectForKey:]: .
Tried to solve but did not get the better solution for it. Please help me to
find the solution. Thanks In Advance
Below is the issues
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM objectForKey:]: unrecognized selector sent to instance 0x19731d40'
This is a debugging problem and nobody can really solve it for you as you are using non-local variables whose definition and values are unknown, don't mention that you are using SBJSON (I guess), etc. But let's see if we can give you some pointers. Your error:
[__NSArrayM objectForKey:]: unrecognized selector sent to instance
That tells you that you sent a dictionary method (objectForKey) to an array (__NSArrayM). So somewhere you have an array when you think you have a dictionary.
Now you declare and allocate a dictionary:
NSMutableDictionary * myDict = [[NSMutableDictionary alloc] init];
but then assign to it:
myDict=[sdf objectAtIndex:i];
So this discards the dictionary you allocated and instead assigns whatever is at index i in the array sdf. How do you know, as opposed to think, that the element of the array is a dictionary? You don't test to check...
So where did sdf come from? This line:
NSMutableArray *sdf = [(NSDictionary*)[responseString JSONValue] objectForKey:#"DataTable"];
So that calls JSONValue on some unknown string, assumes the result is a dictionary (could it be an array? or a failure?), looks up a key (did your error come from this line?), and assumes the result is an array.
So what you need to do is go and test all those assumptions, and somewhere you'll find an array where you think you have a dictionary.
Happy hunting!
YOU FETCH THE VALUE IN ARRAY FORMAT AND YOU INTEGRATE METHOD IN DICTIONARY.
You do not need to iterate keys and values of dict can directly pass values to array inside else part like:
myArray = [sdf objectForKey:#"RxnCustomerProfile"];
Key RxnCustomerProfile itself containing array not dictionary.
Change your if else part use below code:
if (([(NSString*)sdf isEqual: [NSNull null]])) {
// Showing AlertView Here
}else {
myArray = [sdf objectForKey:#"RxnCustomerProfile"];
}
NSMutableArray *sdf = [(NSDictionary*)[responseString JSONValue] objectForKey:#"DataTable"];
Check Sdf
if([sdf isKindOfClass:[NSDictionary class]])
{
NSLog(#"Dictionary");
}
else if([sdf isKindOfClass:[NSArray class]])
{
NSLog(#"NSArray");
}
else if([sdf isKindOfClass:[NSMutableArray class]])
{
NSLog(#"NSMutableArray");
}
First of all it seems like your json is not actually correctly formatted. Without knowing what responseData looks like it's difficult to say exactly what is wrong. But in your code there are a few areas where it can be improved.
First of all you don't need to use [responseString JSONValue]. You can short circuit it entirely with
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
NSArray *sdf = responseDictionary[#"DataTable"];
Now, the rest all depends on the data in responseData.
But you can make your code a little bit cleaner with (if I understand what you're trying to achieve correctly:
NSMutableArray *myArray = [NSMutableArray array];
if ([sdf isEqual:[NSNull null]]) {
// Showing AlertView here
} else {
for (NSDictionary *myDict in sdf) {
[myArray addObject:dict[#"RxnCustomerProfile"]];
}
}
// No idea what you're trying to achieve here, but here goes:
jsonArray = [myArray mutableCopy];
NSDictionary *dict = jsonArray.first;
if (dict.count > 1) {
// Showing AlertView here
}
Some things to note. You make very liberal use of NSMutableArray and NSMutableDictionary for no apparent reason. Only use mutable if you're actually changing the array or dictionary.

How to populate a UIPickerView with results from a NSFetchRequest using Core Data

I have a UIPickerView that I am trying populate with the results from a NSFetchRequest pulling data from a managedObjectContext. When I initialize my UIPickerView with the following, KCModalPickerView *pickerView = [[KCModalPickerView alloc] initWithValues:_userNames]; Xcode doesn't throw and warnings or errors, but when I build and run the app I am getting the following error.
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Account copyWithZone:]: unrecognized selector sent to instance 0x7a60ec70'
* First throw call stack:
Now before you say this error is due to me not implementing the copyWithZone method in my vc, I want to point out that nowhere in my class files am I using the keyword copy
The method that I was told that is causinging the crash belongs to the KCModalPicker class implementation file. And the method looks like the following,
// edit this method
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [self.values objectAtIndex:row];
}
What do I need to change / edit / add to prevent this app from crashing?
Update
_usernames is a NSArray ...the results look like the following,
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Account" inManagedObjectContext:_managedObjectContext];
[fetchRequest setEntity:entity];
fetchRequest.propertiesToFetch = [NSArray arrayWithObject:[[entity propertiesByName] objectForKey:#"username"]];
NSError *error = nil;
NSArray _usernames = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
KCModalPickerView expects an array of NSString, you give it an array of Account. The framework tries to copy your instance because it thinks it's an NSString, which conforms to the NSCopying protocol and implements copyWithZone:. Your object does not, and there will be a [Account copyWithZone:]: unrecognized selector sent to instance exception.
Simply create an array of NSStrings by using the appropriate attribute from your Core Data object.
There are probably smarter ways for this, but this would be the obvious solution:
NSMutableArray *names = [NSMutableArray arrayWithCapacity:[_usernames count]];
for (Account *account in _usernames) {
NSString *accountName = account.name;
if (!accountName) {
accountName = #"<Unknown Account>";
}
[names addObject:accountName];
}
KCModalPickerView *pickerView = [[KCModalPickerView alloc] initWithValues:names];
I just saw that you have set propertiesToFetch. Additionally you have to set resultsType of the fetchRequest to NSDictionaryResultType. In this case executeFetchRequest:error: returns an array of dictionaries. And you should be able to use NSArray *names = [_usernames valueForKey:#"username"]; instead of the for loop.

Delete table row and at the same time object from core data with one button

I have a core data model with single entity objects. Then i load these objects into an array and display them in a table with default cell styles. In the navigation bar there is a delete button that when a row is selected (e.g. object) and this button clicked, it should delete the row and the respective object in the core model. I have seen examples of deleting rows but with a delete button displayed in each row. I want to have only one button in the navig bar and be able to control the deleting of rows from it. I have tried the code below but it does not work. I can't find a way to make it identify the row selected in the delete method. Any help is appreciated.
In viewdidload of the tableviewcontroller class:
UIBarButtonItem *delButton = [[UIBarButtonItem alloc]
initWithTitle:#"Del"
style: UIBarButtonItemStyleBordered
target: self
action:#selector(delItemToArray)];
self.managedObjectContext = ((ecoAppDelegate *) [UIApplication sharedApplication].delegate).managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"FavoritesInfo" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
fetchRequest.resultType = NSDictionaryResultType;
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:#"name", nil]];
NSError *error=nil;
self.favArr=[self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (error!=nil) {
NSLog(#" fetchError=%#,details=%#",error,error.userInfo);
}
self.favName = [self.favArr valueForKey:#"name"];
//Delete Item To table array and delete object to data core model
- (void)delItemToArray {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
[context deleteObject:appDelegatee.favoritesInfo]; // favoritesInfo is the NSManagedObject
NSIndexPath *indexPath;
[favName removeObjectAtIndex:indexPath.row];
[appDelegatee saveContext]; // to save changes in the core data model
[self.tableView reloadData];
}
Error:
[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x8852b90
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x8852b90'
You might got a warning like Incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *' here
self.favArr=[self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
You should make the fetched array mutable for removing objects from it. You can do it like
self.favArr = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
Also change this
self.favName = [self.favArr valueForKey:#"name"];
to
self.favName = [[self.favArr valueForKey:#"name"]mutableCopy];

How to add object of NSDictionary type to an NSMutableArray which contains objects of NSDictionaryResultType?

I am fetching data from Core Data with the following code-
NSManagedObjectContext *context=[[self appDelegate] managedObjectContext];
NSEntityDescription *entityDesc=[NSEntityDescription entityForName:#"Messages" inManagedObjectContext:context];
NSFetchRequest *request=[[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
[request setResultType:NSDictionaryResultType];
NSArray *objects=[context executeFetchRequest:request error:&error];
The function containing the above code returns me the NSArray of NSDictionaryType.
On the view controller i stored them into a NSMutableArray *messages on viewdidload function.
Now if new messages is received or sent , i want to store that new NSDictionary to messages. Doing so is generating error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI addObject:]: unrecognized selector sent to instance 0x9740230'
Code to get data-
CoreDataHandler *handler=[[CoreDataHandler alloc] init];
NSMutableArray *messages=[[NSMutableArray alloc]initWithObjects: nil];
messages=(NSMutableArray *)[handler fetchMessages:[chatWithUser objectForKey:#"jidStr"]];
Code where i am adding object to messages-
NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
[m setObject:messageStr forKey:#"msg"];
[m setObject:#"you" forKey:#"sender"];
[m setObject:[NSString getCurrentTime] forKey:#"createdAt"];
[messages addObject:(NSDictionary *) m];
You should use NSMutableArray instead on NSArray, NSArray doesn't contain method addObject.
You can create mutable copy like:
NSMutableArray *objects=[[context executeFetchRequest:request error:&error] mutableCopy;
Now you are free to call addObject method on that object.
Just because you declare a dog to be a cat, it doesn't mean it will "miau" suddenly. It is still a dog, only in cat's clothing. Now on a serious note.
The problem is that you are trying to put things into an NSArray which is immutable. Once an immutable array is created, you can't change it's content.
You might try this
NSMutableArray *objects=[[context executeFetchRequest:request error:&error] mutable copy];
Could you provide the other pieces of code you're referring to here? (E.g. you say you store the messages obtained from the above fetch into an NSMutableArray. Show the code where it is declared a mutable array, where it is instanciated and the code where the fetch results are added).
Judging by the error message you are trying to add an object to an NSArray, not to an NSMutableArray.
Could you provide the other pieces of code you're referring to here? (E.g. you say you store the messages obtained from the above fetch into an NSMutableArray. Show the code where it is declared a mutable array, where it is instanciated and the code where the fetch results are added).
Judging by the error message you are trying to add an object to an NSArray, not to an NSMutableArray.
OK, so you are creating an NSMutableArray and storing its pointer in 'messages'. But then you assign a different pointer to 'messages'. You assign the non mutable result set to it.
You should not do that. Instead of that just add the objects from the fetch to the messages object.
Something like [messages addObjectsFromArray: fetchresults];

iOS Terminating app due to uncaught exception 'NSUnknownKeyException'

I am pretty new to objective c and iOS programming, and I have this pretty strange error. The app in question initializes a NSMutableArray with a preset set of values of a custom type I made using NSObject. Which is manipulated by the app. If new values are added during app run time, they are saved using NSUserDefaults, and are brought up from NSUserDefaults along with the default values on next app open.
This is the error I get:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFConstantString 0xb404> valueForUndefinedKey:]: this class is not key value coding-compliant for the key score.'
*** First throw call stack:
(0x1c9b012 0x10d8e7e 0x1d23fb1 0xb84d1d 0xaf100b 0xaf0fbd 0xb0f247 0xb3023c 0xb30056 0x3e40 0x3c5f 0x11f5ad 0x10ec705 0x202c0 0x20258 0x242ff4 0x10ec705 0x202c0 0x20258 0xe1021 0xe157f 0xe1056 0x246af9 0x10ec705 0x202c0 0x20258 0xe1021 0xe157f 0xe06e8 0x4fcef 0x4ff02 0x2dd4a 0x1f698 0x1bf6df9 0x1bf6ad0 0x1c10bf5 0x1c10962 0x1c41bb6 0x1c40f44 0x1c40e1b 0x1bf57e3 0x1bf5668 0x1cffc 0x290d 0x2835)
libc++abi.dylib: terminate called throwing an exception
I am not quite sure what the error is or how to go about debugging it.
Previously this code worked flawlessly, all I did was remove one or two elements from the preset default list of elements, and in the simulator, simulated deleting the app, and recompiled the code. Ever since my program crashes, with the above message, and I can't figure out how to fix it.
So if someone can give me some help on how to go about debugging this, that would be wonderful. I can attach code as needed, i'm not sure what code would be relevant to be shown, and it may be too much to post all the code involved in the project.
Code to encode and decode the properties of my custom Name NSObject class called name.h:
-(void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.name forKey:#"name"];
[encoder encodeInteger:self.score forKey:#"score"];
}
-(id)initWithCoder:(NSCoder *)decoder
{
if((self = [super init]))
{
self.name = [decoder decodeObjectForKey:#"name"];
self.score = [decoder decodeIntegerForKey:#"score"];
}
return self;
}
Retrieving Data from class, incase this matters, this code occurs in appdelegate.m:
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:#"dataArray"];
NSInteger score = 0;
NSMutableArray *temp = [[NSMutableArray alloc] initWithObjects:#"name", nil];
NSMutableArray *tempList = [[NSMutableArray alloc] init];
for(NSString *y in temp)
{
Name *name = [[Name alloc] init];
name.name = y;
name.score = score;
[tempList addObject:name];
}
if (data)
{
NSArray *list = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSMutableArray *names = [[NSMutableArray alloc]initWithArray:list];
// [_nameList addObjectsFromArray:temp];
NSMutableArray *t = [[names arrayByAddingObjectsFromArray:tempList ] mutableCopy];
_nameList = [[NSMutableArray alloc]init];
[_nameList addObjectsFromArray:t];
}
else
{
//First time load or data is not saved yet
_nameList = [[NSMutableArray alloc] initWithObjects:#"name", nil];
}
saving the array at close time:
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
NSData *data =[NSKeyedArchiver archivedDataWithRootObject:_nameList];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"dataArray"];
}
same code is in applicationDidEnterBackground.
code to sort by 'score'
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController: (UIViewController *)viewController
{
if(viewController == _viewController3)
{
[self sortNames:_nameList];
[[(ThirdViewController*)_viewController3 topList] reloadData];
}
}
-(void)sortNames:(NSMutableArray*)test
{
NSArray* temp = [[NSArray alloc] initWithArray:test];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"score" ascending:NO];
NSArray *sortedLinks = [[temp sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]] mutableCopy];
_nameList = (NSMutableArray*) sortedLinks;
}
Here's my two cents. You have this line:
[encoder encodeObject:self.name forKey:#"name"];
And then this line:
Name *name = [[Name alloc] init];
This makes me think that the "self.name" property is one of these "Name" custom subclasses.
I believe that if you make a custom subclass and you want it to encodewithcoder, you have to add the encodewithcoder method to your custom subclass and have it encodewithcoder all of its properties and instance variables as primitively as you can.
Meaning, your Name class needs to have its own encodewithcoder method that encodes all of its properties and instance variables that have been stored as factory objects or c primitives.
Edit: I'm still pretty new and value my rep. If I'm wrong, please comment and I'll delete but please don't downvote me to oblivion
Here:
_nameList = [[NSMutableArray alloc] initWithObjects:#"name", nil];
you are adding an NSString to the _nameList array. Later you save that array.
The next time you load that array, you have the NSString #"name" in it. I guess at some point you iterate through the items in _nameList and try to get or set the score, since you are calling this on a subclass of NSString you get the NSUnknownKeyException.
I think what you want to is to replace the line above with something like this: (assuming the class in your name.h file you mentioned above is called Name)
Name *newName = [[Name alloc] init]; //or initialize the way you need to
_nameList = [[NSMutableArray alloc] initWithObjects:newName, nil];

Resources