Unrecognized selector sent to instance with TableViewController - ios

I'm very new to Obj-c and I'm now creating a tableview to show what I have parsed from Json. Here's the code:
#import "ClasstableViewController.h"
#interface ClasstableViewController ()
#end
#implementation ClasstableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"JSONRead";
NSString *testUrl = #"example.com";
NSURL *url = [NSURL URLWithString:testUrl];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10];
NSData *JSONData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSArray *jsonResult = [NSJSONSerialization JSONObjectWithData:JSONData options:kNilOptions error:nil];
self.data = jsonResult;
NSMutableArray *_names = [NSMutableArray array];
for (id item in jsonResult)
[_names addObject:[NSString stringWithFormat:#"%#", item[#"Mon"]]];
self.names = _names;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [self.names count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.text = self.names[indexPath.row];
return cell;
}
and I have change my tableview to the correct class in the identity inspector to ClasstableViewController, I see others have resolve their issues with this solution.
but I'm still getting this:
-[__NSCFString objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7fd8835691c0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7fd8835691c0'
anyone have any idea why?

Probably your NSArray *jsonResult is an array of NSStrings, or contain some NSStrings as objects. So when you do
for (id item in jsonResult)
[_names addObject:[NSString stringWithFormat:#"%#", item[#"Mon"]]];
you are supposing that item is a NSDictionary, but it isn't.

for (id item in jsonResult)
[_names addObject:[NSString stringWithFormat:#"%#", item[#"Mon"]]];
item is NSString not NSDictionary,use like below
for (id item in jsonResult)
[_names addObject:[NSString stringWithFormat:#"%#", item]];
Use JSONEditor to check the JSON.

Related

Obj-C: Only return 1 cell (top cell) if cells proceeding contain the same UILabel values?

The top 3 cells in my tableview have a label that says the word 'Squirrels'. Is there a way to make it so that if a UILabel says 'Squirrels' in more than one cell in my table, to only show the first cell of the three?
E.g. if UILabel userName in tableviewCell is equal to #"Squirrels", only show one table
view cell in the table that contains Squirrels in the UILabel
Hope this makes sense. Thanks in advance!
EDIT: I've successfully retrieved the first array containing more than one common 'name' value (see edit to code below). That said, when I try and display these values (firstFoundObject) in my tableview I get the following crash error:
-[__NSDictionaryI objectAtIndex:]: unrecognized selector sent to instance 0x1c01a5a20 2017-10-03 23:01:51.728128-0700
pawswap[623:85420] *** Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSDictionaryI
objectAtIndex:]: unrecognized selector sent to instance 0x1c01a5a20'
ViewController.m
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *nodeTitle = self.messages[0][#"name"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name == %#", nodeTitle];
NSArray *filteredArray = [self.messages filteredArrayUsingPredicate:predicate];
id firstFoundObject = nil;
firstFoundObject = filteredArray.count > 0 ? filteredArray.firstObject : nil;
NSMutableArray *firstObjects = firstFoundObject;
return [firstObjects count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *nodeTitle = self.messages[0][#"name"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name == %#", nodeTitle];
NSArray *filteredArray = [self.messages filteredArrayUsingPredicate:predicate];
id firstFoundObject = nil;
firstFoundObject = filteredArray.count > 0 ? filteredArray.firstObject : nil;
NSMutableArray *firstObjects = firstFoundObject;
static NSString *PointsTableIdentifier = #"MyMessagesCell";
MyMessagesCell *cell = (MyMessagesCell *)[tableView dequeueReusableCellWithIdentifier:PointsTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MyMessagesCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSDictionary *receivedSubjectLine = [firstObjects objectAtIndex:indexPath.row];
NSString *messageSubject = [receivedSubjectLine objectForKey:#"node_title"];
[cell.subjectLine setText:messageSubject];
NSDictionary *fromUser = [firstObjects objectAtIndex:indexPath.row];
NSString *userName = [fromUser objectForKey:#"name"];
[cell.senderName setText:userName];
NSDictionary *receivedBody = [firstObjects objectAtIndex:indexPath.row];
NSString *messageBody = [receivedBody objectForKey:#"body"];
[cell.fullMessage setText:messageBody];
NSDictionary *messageReceived = [firstObjects objectAtIndex:indexPath.row];
NSString *timeReceived = [messageReceived objectForKey:#"published at"];
NSLog(#"Message Received at %#", timeReceived);
[cell.receivedStamp setText:timeReceived];
return cell;
}
PREVIOUS
ViewController.m
#pragma mark - Table view data source
- (int)numberOfSectionsInTableView: (UITableView *)tableview
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.messages count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *PointsTableIdentifier = #"MyMessagesCell";
MyMessagesCell *cell = (MyMessagesCell *)[tableView dequeueReusableCellWithIdentifier:PointsTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MyMessagesCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSDictionary *receivedSubjectLine = [self.messages objectAtIndex:indexPath.row];
NSString *messageSubject = [receivedSubjectLine objectForKey:#"node_title"];
[cell.subjectLine setText:messageSubject];
NSDictionary *fromUser = [self.messages objectAtIndex:indexPath.row];
NSString *userName = [fromUser objectForKey:#"name"];
[cell.senderName setText:userName];
NSDictionary *receivedBody = [self.messages objectAtIndex:indexPath.row];
NSString *messageBody = [receivedBody objectForKey:#"body"];
[cell.fullMessage setText:messageBody];
NSDictionary *messageReceived = [self.messages objectAtIndex:indexPath.row];
NSString *timeReceived = [messageReceived objectForKey:#"published at"];
[cell.receivedStamp setText:timeReceived];
return cell;
}
Basically the problem you are getting is due to firstObject is of type Dictionary and you are type casting it to NSMutableArray. Please check below line:
id firstFoundObject = nil; firstFoundObject = filteredArray.count > 0
? filteredArray.firstObject : nil;
If you see you have filteredArray.firstObject as Dictionary in your application which you capture in firstFoundObject but later you are making it NSMutableArray type here:
NSMutableArray *firstObjects = firstFoundObject;
And later when you try to get here, it crashes
NSDictionary *receivedSubjectLine = [firstObjects
objectAtIndex:indexPath.row];
The correct - basic - version of your code should look like
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *PointsTableIdentifier = #"MyMessagesCell";
MyMessagesCell *cell = (MyMessagesCell *)[tableView dequeueReusableCellWithIdentifier:PointsTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MyMessagesCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
[cell.subjectLine setText:[self.recvMessage objectForKey:#"node_title"]];
[cell.senderName setText:[self.recvMessage objectForKey:#"name"]];
[cell.fullMessage setText:[self.recvMessage objectForKey:#"body"]];
[cell.receivedStamp setText:[self.recvMessage objectForKey:#"published at"]];
return cell;
}
Though it is not optimised but still it can do work for you.
COUNT ISSUE:
NSMutableDictionary *firstObjects = firstFoundObject;
return [firstObjects count];
In your code above you have inside the numberOfRowsInSection since you have firstFoundObject as dictionary so when you call [firstObjects count] which is a valid call and it returns the number of key in the dictionary.
You have modify it like :
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
NSInteger rowCount = filteredArray.count;
self.recvMessage = rowCount? filteredArray.firstObject: nil;
return rowCount? 1: 0;
}
and you have new data which actually stores the filtered object.
#property (nonatomic) NSDictionary *recvMessage;
Hope this helps.
Yes you can do it easily,
You will do it before run tableView,
for example :
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableDictionary* NameDictionary=[[NSMutableDictionary alloc] init];
NSString* PreviousName;
int oneTime=0;
for(int i=0;i<[self.messages count];i++){
NSDictionary *fromUser = [self.messages objectAtIndex: i];
NSString *userName = [fromUser objectForKey:#"name"];
if(oneTime==0)
{
PreviousName=userName;
[NameDictionary addObject:[self.messages objectAtIndex: i]];
oneTime=1;
}
if(oneTime!=0)
{
if([PreviousName isEqualToString: userName])
{
}
else{
[NameDictionary addObject:[self.messages objectAtIndex: i]];
}
PreviousName=userName;
}
}
}
When you ask to filter out cells with a senderName property equal to #"Squirrels", you're effectively asking to change your datasource after it has been set. This will cause problems in your numberOfRowsInSection method, which will return more rows than you need if any filtering takes place after the datasource is set.
As one of the comments to your answer suggests, "make a secondary array which contains unique elements of self.messages and work with this array." The array that makes up the datasource of the tableview should require no filtering. The tableview should just be able to present it.
If I had enough reputation to comment on the above answer, I would say that you're right that it doesn't work because self.messages doesn't change. Instead of collecting the "non-duplicate" objects in NameDictionary, consider collecting them in an NSMutableArray. This new, filtered array should be the datasource for your array. You may want to filter this array outside of this ViewController so that once the array arrives at this view controller it can just be assigned to self.messages.
If you're looking to exclude all duplicates, as opposed to just duplicates that appear next to each other, consider this answer.

Json data Crash '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x10a860840

This is my code, I want to display Json data on UITableview. My app Crash on due to This reason '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x10a860840. i am new to Json.
- (void)viewDidLoad
{
[super viewDidLoad];
NSError *error;
NSString *url_string = [NSString stringWithFormat: #"http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo"];
NSURL *blogURL = [NSURL URLWithString:url_string];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSDictionary *dataDictionary = [NSJSONSerialization
JSONObjectWithData:jsonData options:0 error:&error];
//NSLog(#"Data : %#",dataDictionary);
for (NSDictionary *bpDictionary in dataDictionary)
{
NSobjectClass *currenHotel = [[NSobjectClass alloc]initWithcountrycode:[bpDictionary
objectForKey:#"countrycode"] name:[bpDictionary objectForKey:#"name"] toponmyName:[bpDictionary objectForKey:#"toponmyName"] population:[bpDictionary
objectForKey:#"population"]];
[self.objectHolderArray addObject:currenHotel];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section
{
return [self.objectHolderArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
Cell1 *cell = [self.JsonTableview dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
NSobjectClass *currentHotel = [self.objectHolderArray
objectAtIndex:indexPath.row];
cell.countryCode.text = currentHotel.countrycode;
cell.countryName.text = currentHotel.name;
cell.countrytype.text = currentHotel.toponmyName;
cell.population.text = currentHotel.population;
return cell;
}
Please check my Code.

-[__NSCFString objectAtIndex:] cellForRowAtIndexPath: crashes when trying to access arrays objectAtIndex:indexPath.row

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectAtIndex:]: unrecognized selector sent to instance 0xa84a800'
I am loading in data to a UITableView, from a custom UITableViewCell (own class and nib). It works great, Until i try to access the objectAtIndex:indexPath.row for some arrays.
I'll post my code first, It will probably be easier for you to understand what I mean then.
-(void)viewWillAppear:(BOOL)animated
{
self.navigationController.navigationBarHidden=YES;
if (managedObjectContext==nil) {
MFAppDelegate *appDelegate = (MFAppDelegate *)[UIApplication sharedApplication].delegate;
managedObjectContext = appDelegate.managedObjectContext;
}
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Last" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
// Set self's events array to the mutable array, then clean up.
[self setFinal:mutableFetchResults];
lastdisarr=[mutableFetchResults valueForKey:#"lastdis"];
lastcalarr=[mutableFetchResults valueForKey:#"lastcal"];
lasttimearr=[mutableFetchResults valueForKey:#"lasttime"];
date=[mutableFetchResults valueForKey:#"lastspeed"];
lasticonarr=[mutableFetchResults valueForKey:#"iconwe"];
NSLog(#"LAst DISTANCE %#",lasticonarr);
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
Cell *cell = [table dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle]loadNibNamed:#"Cell" owner:self options:nil];
cell=self.custom;
}
// Set up the cell...
cell.distance.text=[lastdisarr objectAtIndex:indexPath.row];
cell.timelab.text=[lasttimearr objectAtIndex:indexPath.row];
cell.callab.text=[lastcalarr objectAtIndex:indexPath.row];
cell.date.text=[date objectAtIndex:indexPath.row];
//cell.wether.image=[lasticonarr objectAtIndex:indexPath.row];
NSMutableArray *ar=[lasticonarr objectAtIndex:indexPath.row];
NSLog(#"%#",ar);
//problem is here
//i want to show image in custom cell & get path from core data....path is getting but image not show on cell
NSURL *url1 = [NSURL URLWithString:[ar objectAtIndex:indexPath.row]];
NSLog(#"%#",url1);
NSData *data = [NSData dataWithContentsOfFile:[ar description]];
NSLog(#"%#",data);
return cell;
}
there are two option:
1: you haven't retained your value;
lastdisarr = [[mutableFetchResults valueForKey:#"lastdis"] retain];
lastcalarr = [[mutableFetchResults valueForKey:#"lastcal"] retain];
lasttimearr = [[mutableFetchResults valueForKey:#"lasttime"] retain];
2: [mutableFetchResults valueForKey:#"lastdis"] is an NSString, and not an NSArray, as expected.

ObjectAtIndex Crash

Program crashes at the line with comments below. Not sure what's wrong. Any tips for a 1st time programmer?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MainCell"];
}
cell.textLabel.text = [[users objectAtIndex:indexPath.row] objectForKey:[[NSString alloc] initWithFormat:#"%d", indexPath.row]];
//My program runs but then crashes at this line, I have no idea what's wrong with it though "reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance"
return cell;
}
Some More Code (Not all of it though) As Requested
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
users = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
[self.tableView reloadData];
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [users count];
}
In .h file
#interface GIFUsersListViewController : UITableViewController {
NSArray *users;
NSMutableData *data;
} #end
As of this message: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance it looks like users is not NSArray, its rather NSDictionary.
If you're not sure what is in JSON then check it before assigning to users:
id usersFromJSON = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
if ([usersFromJSON isKindOfClass:[NSArray class]]) {
users = usersFromJSON;
} else {
NSLog(#"Something wrong with my JSON: %#", usersFromJSON);
}

Problem in loading a NSMutablearray value into table view?

I am new to iphone development, I am trying to load a NSMutableArray values into a table view, I am using code below for this which generates error as specified. Can some one help me in rectifying this error.
code :-
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [ShowList count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
NSString *cellValue = [ShowList objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
error :-
2011-02-25 07:22:24.470 iPhone[1032:207] -[__NSArrayM isEqualToString:]: unrecognized selector sent to instance 0xab15d30
2011-02-25 07:22:24.471 iPhone[1032:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM isEqualToString:]: unrecognized selector sent to instance 0xab15d30'
*** Call stack at first throw:
Print Description of My NSMutableArray :-
2011-02-25 07:21:54.806[1032:207] (
(
"viral_tweeter",
default1571546,
default1570056,
twilightsaga,
"wp-monetizer",
viraltweetbuild,
"building_a_list",
yourtwittertips,
"twitter_profit",
mikesbi,
mikesbizz,
default1164341,
incbizztest,
default1164319,
iprotv,
iwantafreecopy1,
tweeterbuilder,
trafficlists,
myadsensenews,
mysafelistnews,
myviralnews,
safelistology,
slmembers,
slpmembers,
twonderlandlist,
noseospider,
yseospider,
digitallockdown,
alistblueprint,
classifiedtips,
incbizzblog,
"xit-trafficbeta",
twwidget,
jvtrafficfunnel,
instantmlmspage,
listbuldingmax,
"incbizz_tips"
)
)
code for parsing HTTP Get response :-
- (void)requestDataFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error {
// this is only for testing whether the data is coming or not
// NSDictionary *tempDict = [GTMOAuthAuthentication dictionaryWithResponseData:data];
if (error)
{
NSLog(#"Error: in getting data after authentication : %#",[error description]);
}
else
{
// NSLog(#"Succcess: in getting data after authentication \n data: %#",[tempDict description]);
NSString* aStr;
aStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSDictionary *dictionary = [aStr JSONValue];
NSArray *keys = [dictionary allKeys];
Names = [[NSMutableArray alloc]init];
int i = 0;
// values in foreach loop
for (NSString *key in keys)
{
i++;
NSArray *items = (NSArray *) [dictionary objectForKey:key];
// NSLog(#" test %#", items);
if (i==3)
{
for (NSString *item in items)
{
NSString* aStrs= item;
// NSLog(#" test %#", aStrs);
NSDictionary *dict = aStrs;
NSArray *k = [dict allKeys];
for (id *it in k)
{
// NSLog(#"the child item: %#", [NSString stringWithFormat:#"Child Item -> %# value %#", (NSDictionary *) it,[dict objectForKey:it]]);
NSString *value = [it description];
if ( [value isEqualToString:#"name"])
{
NSString * value = (NSString*)[[dict objectForKey:it] description];
NSLog(value);
[Names addObject:value];
[[MySingletonClass sharedMySingleton] SetAweberList: value];
}
}
}
}
}
mShowList.hidden = FALSE;
}
}
#Ravi your array is array of array that is the ShowList is an array which has first object as array and that array is that
"viral_tweeter",
default1571546,
default1570056,
twilightsaga,
"wp-monetizer",
viraltweetbuild,
"building_a_list",
yourtwittertips,
"twitter_profit",
mikesbi,
mikesbizz,
default1164341,
incbizztest,
default1164319,
iprotv,
iwantafreecopy1,
tweeterbuilder,
trafficlists,
myadsensenews,
mysafelistnews,
myviralnews,
safelistology,
slmembers,
slpmembers,
twonderlandlist,
noseospider,
yseospider,
digitallockdown,
alistblueprint,
classifiedtips,
incbizzblog,
"xit-trafficbeta",
twwidget,
jvtrafficfunnel,
instantmlmspage,
listbuldingmax,
"incbizz_tips"
so you can do something like this.
NSString *cellValue = [[ShowList objectAtIndex:0] objectAtIndex:indexPath.row];
I assume UILabel's setText calls isEqualToString for some reason, so it crashes for the very first object in your array which is not a NSString.

Resources