Unrecognized Selector sent to Instance when parsing RSS Feed - ios

The feed in question is https://fritchcoc.podbean.com/feed/
I have this in my code to parse, but every time I run it, I get an error message of the following. I have tried to add exception breakpoints, but it is not showing me the line of code causing all the commotion. I have spent two hours on this with no luck at all figuring out the issue. I set every NSString to nil within the commands, just in case one of the item valueForChild was coming up with errors, but even with all nils, they had issues.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RSSEntry initWithBlogTitle:articleTitle:articleUrl:articleDate:articleImage:contentEncoded:]: unrecognized selector sent to instance
- (void)viewDidLoad {
[super viewDidLoad];
self.allEntries = [NSMutableArray array];
self.queue = [[[NSOperationQueue alloc] init] autorelease];
self.feeds = [NSArray arrayWithObjects:#"https://fritchcoc.podbean.com/feed/",
nil];
[self refresh];
}
- (void)refresh {
for (NSString *feed in _feeds) {
NSURL *url = [NSURL URLWithString:feed];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[_queue addOperation:request];
}
}
- (void)parseFeed:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
if ([rootElement.name compare:#"rss"] == NSOrderedSame) {
[self parseRss:rootElement entries:entries];
} else if ([rootElement.name compare:#"feed"] == NSOrderedSame) {
[self parseAtom:rootElement entries:entries];
} else {
NSLog(#"Unsupported root element: %#", rootElement.name);
}
}
- (void)requestFinished:(ASIHTTPRequest *)request {
[_queue addOperationWithBlock:^{
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:[request responseData]
options:0 error:&error];
if (doc == nil) {
NSLog(#"Failed to parse %#", request.url);
} else {
NSMutableArray *entries = [NSMutableArray array];
[self parseFeed:doc.rootElement entries:entries];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//int newCounter = 0;
for (RSSEntry *entry in entries) {
// newCounter++;
int insertIdx = [_allEntries indexForInsertingObject:entry sortedUsingBlock:^(id a, id b) {
RSSEntry *entry1 = (RSSEntry *) a;
RSSEntry *entry2 = (RSSEntry *) b;
return [entry1.articleDate compare:entry2.articleDate];
}];
[_allEntries insertObject:entry atIndex:insertIdx];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:insertIdx inSection:0]]
withRowAnimation:nil];
/* if (newCounter > 999) {
break;
}*/
}
}];
}
}];
}
- (void)requestFailed:(ASIHTTPRequest *)request {
NSError *error = [request error];
NSLog(#"Error: %#", error);
[self refresh];
}
- (void)parseRss:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
NSLog(#"Go");
NSArray *channels = [rootElement elementsForName:#"channel"];
for (GDataXMLElement *channel in channels) {
NSString *blogTitle = [channel valueForChild:#"title"];
NSArray *items = [channel elementsForName:#"item"];
for (GDataXMLElement *item in items) {
NSString *articleTitle = [item valueForChild:#"title"];
NSString *articleDateString = [item valueForChild:#"pubDate"];
NSString *theCategory = [item valueForChild:#"category"];
NSDate *articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822];
NSString *articleUrl = [[[[item elementsForName: #"enclosure"] lastObject] attributeForName: #"url"] stringValue];
NSString *picture = [[[[item elementsForName: #"media:content"] lastObject] attributeForName: #"href"] stringValue];
RSSEntry *entry = [[[RSSEntry alloc] initWithBlogTitle:blogTitle
articleTitle:articleTitle
articleUrl:articleUrl
articleDate:articleDate
articleImage:picture
contentEncoded:nil
category:theCategory] autorelease];
if ([theCategory isEqualToString:#"Sermon"]) {
[entries addObject:entry];
}
}
}
}

In your code you have this call:
RSSEntry *entry = [[[RSSEntry alloc] initWithBlogTitle:blogTitle
articleTitle:articleTitle
articleUrl:articleUrl
articleDate:articleDate
articleImage:picture
contentEncoded:nil
category:theCategory] autorelease];
It has a "category" last parameter, but your error message doesn't have it:
Terminating app due to uncaught exception
'NSInvalidArgumentException',
reason: '-[RSSEntry initWithBlogTitle:articleTitle:articleUrl:articleDate:articleImage:contentEncoded:]:
unrecognized selector sent to instance
Is it possible that you have made a new version of RSSEntry that has "category", but didn't recompile properly some of your parsing code, and that code is still trying to call an old method (without "category")?
If so, just do a Product - "Clean" - "Build", and pay attention to compilation errors an warnings.
I've noticed that you still are not using ARC (calling "autorelease"), which indicates to me that it's a really old code :)

Related

Getting delay to see next view controller ,see detail in post?

I have one login screen after that it will move to next view controller which have i have used some networks like http,json to get data from server. when i enter login username/password then if i click login button its getting delay to 8 seconds after that only it moving to next view controller.Still that my login screen alone showing for 8 seconds and then only it move to next view controller.
Here my login controller.m:
#implementation mainViewController
- (void)viewDidLoad {
[super viewDidLoad];
_username.delegate = self;
_password.delegate = self;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults boolForKey:#"reg"]) {
NSLog(#"no user reg");
_logBtn.hidden = NO;
}
}
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
_username.text = nil;
_password.text = nil;
}
- (IBAction)LoginUser:(id)sender {
if ([_username.text isEqualToString:#"sat"] && [_password.text isEqualToString:#"123"]) {
NSLog(#"Login success");
[self performSegueWithIdentifier:#"nextscreen" sender:self];
}
else {
NSLog(#"login was unsucess");
// Alert message
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"wrong"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *actionOk = [UIAlertAction actionWithTitle:#"Ok"
style:UIAlertActionStyleDefault
handler:nil];
[alertController addAction:actionOk];
[self presentViewController:alertController animated:YES completion:nil];
}
}
Here my nextcontroller.m
- (void)viewDidLoad {
[super viewDidLoad];
//for search label data
self.dataSourceForSearchResult = [NSArray new];
//collection of array to store value
titleArray = [NSMutableArray array];
// here only i am getting data from server
[self getdata];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
[self.collectionView reloadData];
}
Help me out. If my question din't understand.I can tell more about my post. And in my nextcontroller.m [self getdata] is i am getting data from server url.Thanks
My get data:
-(void)getdata {
NSString *userName = #“users”;
NSString *password = #“images”;
NSData *plainData = [password dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [plainData base64EncodedStringWithOptions:0];
base64String=[self sha256HashFor: base64String];
NSString *urlString = #"https://porterblog/image/file”;
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"GET"];
NSString *authStr = [NSString stringWithFormat:#"%#:%#", userName, base64String];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64EncodedStringWithOptions:0]];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSError * error;
self->arrayPDFName = [[NSMutableArray alloc]init];
NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableContainers error:nil];
NSDictionary *dictOriginal = jsonResults[#“birds”];
[titleArray addObject:[NSString stringWithFormat:#" birds(%#)”, dictOriginal[#"count"]]];
NSDictionary *dictOriginal2 = jsonResults[#"owl”];
[titleArray addObject:[NSString stringWithFormat:#" Owl(%#)”, dictOriginal2[#"count"]]];
NSDictionary *dictOriginal3 = jsonResults[#"pensq”];
[titleArray addObject:[NSString stringWithFormat:#" Pensq(%#)”, dictOriginal3[#"count"]]];
NSDictionary *dictOriginal4 = jsonResults[#“lion”];
[titleArray addObject:[NSString stringWithFormat:#" lion(%#)”, dictOriginal4[#"count"]]];
NSArray *arrayFiles = [NSArray arrayWithObjects: dictOriginal, dictOriginal2, dictOriginal3, dictOriginal4, nil];
NSLog(#"str: %#", titleArray);
for (NSDictionary *dict in arrayFiles) {
NSMutableArray *arr = [NSMutableArray array];
NSArray *a = dict[#"files"];
for(int i=0; i < a.count; i ++) {
NSString *strName = [NSString stringWithFormat:#"%#",[[dict[#"files"] objectAtIndex:i] valueForKey:#"name"]];
[arr addObject:strName];
}
[arrayPDFName addObject:arr];
}
NSString *errorDesc;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory1 = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory1 stringByAppendingPathComponent:#"SampleData.plist"];
NSString *error1;
returnData = [ NSPropertyListSerialization dataWithPropertyList:jsonResults format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];
if(returnData ) {
if ([returnData writeToFile:plistPath atomically:YES]) {
NSLog(#"Data successfully saved.");
}else {
NSLog(#"Did not managed to save NSData.");
}
}
else {
NSLog(#"%#",errorDesc);
}
NSDictionary *stringsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
}
EDITED:
`- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
self.dataSourceForSearchResult = [NSArray new];
titleArray = [NSMutableArray array];
//Background Tasks
[self getdata];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
[self.collectionView reloadData];
self.navigationItem.hidesBackButton = YES;
});
});
}`
You're getting your data using main thread you need do to that in background then invoke the code you need (as i see is reload collectionView)
I assume that because you didn't show the getdata method code
If that the case you can use this code:
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Tasks
[self getdata];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
[self.collectionView reloadData];
});
});
It's mean that your VC will show immediately but the collectionView fill after you finish load the data, you can put some old data while loading like Facebook app (you see latest retrieved posts until finish loading].
Edit:
In your code you replace viewdidload method in nextController with next code:
- (void)viewDidLoad {
[super viewDidLoad];
//for search label data
self.dataSourceForSearchResult = [NSArray new];
//collection of array to store value
titleArray = [NSMutableArray array];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Tasks
[self getdata];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
[self.collectionView reloadData];
});
});
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
}

PickerView loading data issue

I am loading data from server which is working fine without problem and I can see res value in the NSLog as
2013-11-19 16:22:48.799 Paaa[4278:a0b] res ( { "choice_name" = "DATA0"; }, { "choice_name" = "DATA1"; }, { "choice_name" = "DATA2"; } )The problem is I can't view it in the `pickerView` It always indicate to `return [res count]` as EXC_BAD_ACCESS. So please where would be my problem?
.H:
#property (nonatomic, strong) NSMutableArray *res;
.M:
- (void)requestPos:(ASIFormDataRequest *)request{
NSData *responseData = [request responseData];
NSString *jsonString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
// Create a dictionary from the JSON string
NSDictionary *result = [jsonString JSONValue];
[jsonString release];
CXMLDocument *doc = [[[CXMLDocument alloc] initWithXMLString:[result objectForKey:#"Response"] options:0 error:nil] autorelease];
NSArray *nodes = [doc nodesForXPath:#"/root" error:nil];
NSArray *nodes3 = NULL;
nodes3 = [doc nodesForXPath:#"/root/cl_choicelist/cl_choice" error:nil];
NSLog(#"node3%#", nodes3);
// we will put parsed data in an a array
res = [[NSMutableArray alloc] init];
for (CXMLElement *node in nodes3) {
NSMutableDictionary *item = [[NSMutableDictionary alloc] init];
int counter;
for(counter = 0; counter < [node childCount]; counter++) {
// common procedure: dictionary with keys/values from XML node
[item setObject:[[node childAtIndex:counter] stringValue] forKey:[[node childAtIndex:counter] name]];
}
// and here it is - attributeForName! Simple as that.
[item setObject:[[node attributeForName:#"choice_name"] stringValue] forKey:#"choice_name"]; // <------ this magical arrow is pointing to the area of interest.
[res addObject:item];
[item release];
}
NSLog(#"res %#", res);
[res release];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [res count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [[res objectAtIndex:row]objectForKey:#"choice_name"];
}
- (IBAction)openPickerView{
[actionSheet showInView:self.view];
[UIView beginAnimations:nil context:nil];
[actionSheet setBounds:CGRectMake(0, 0, 320, 492)];
[UIView commitAnimations];
}
Don't release res at the end of requestPos:
If Bhumeshwer katre won't write his answer, then I will :)

UI hanging on background rss parsing

I'm trying to create a simple rss reader. The code works okay, except the UI hangs when the feeds are being updated. I thought I cobbled together the code to get the feed and parse it on a background queue while updating the UI on the mainQueue, but the table hangs pretty badly. Code below:
-(void)refreshFeed2
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
for (NSString *feed in _feeds) {
// iterate over all feeds
NSLog(#"feed=%#", feed);
NSURL *url = [NSURL URLWithString:feed];
// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
(void)[conn initWithRequest:request delegate:self];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if ([data length] == 0 && error == nil) {
// handle empty response
} else if (error != nil) {
// handle error
NSLog(#"Error %#", [error localizedDescription]);
} else if ([httpResponse statusCode] == 200) {
// data present and no errors
[queue addOperationWithBlock:^{
// parse feed on queue
RXMLElement *rss = [RXMLElement elementFromXMLData:data];
RXMLElement *rssChild = [rss child:#"channel"];
RXMLElement* title = [rssChild child:#"title"];
NSArray* items = [[rss child:#"channel"] children:#"item"];
NSMutableArray* result=[NSMutableArray array];
for (RXMLElement *e in items) {
// iterate over the articles
RSSArticle* article = [[RSSArticle alloc] init];
article.sourceTitle = [title text];
article.articleTitle = [[e child:#"title"] text];
article.articleDescription = [[e child:#"description"] text];
article.articleUrl = [NSURL URLWithString: [[e child:#"link"] text]];
NSString *articleDateString = [[e child:#"pubDate"] text];
article.articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822];
if (article.articleUrl != NULL) {
[result addObject:article];
}
}
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// update table on mainQueue
for (RSSArticle *article in result) {
// iterate over articles
int insertIdx = [_allEntries indexForInsertingObject:article sortedUsingBlock:^(id a, id b) {
RSSArticle *entry1 = (RSSArticle *) a;
RSSArticle *entry2 = (RSSArticle *) b;
return [entry1.articleDate compare:entry2.articleDate];
}];
[_allEntries insertObject:article atIndex:insertIdx];
[self.LeftTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:insertIdx inSection:0]]
withRowAnimation:UITableViewRowAnimationFade];
}
}];
}];
}
}];
// Stop refresh control
[refreshControl endRefreshing];
}
}
Code that calls refreshFeed2:
- (void)viewDidLoad {
[super viewDidLoad];
self.allEntries = [NSMutableArray array];
self.feeds = [NSArray arrayWithObjects:
#"http://feeds.washingtonpost.com/rss/politics",
#"http://rss.cnn.com/rss/cnn_allpolitics.rss",
#"http://www.npr.org/rss/rss.php?id=1012",
#"http://www.slatedigital.com/support/feeds/rss_kb.php?s=fd5aa35e773dc3177b85a2126583f002",
nil];
}
//add refresh control to the table view
refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self
action:#selector(refreshInvoked:forState:)
forControlEvents:UIControlEventValueChanged];
NSString* fetchMessage = [NSString stringWithFormat:#"Fetching Articles"];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:fetchMessage
attributes:#{NSFontAttributeName:[UIFont fontWithName:#"Helvetica" size:11.0]}];
[self.LeftTableView addSubview: refreshControl];
[self refreshInvoked:self forState:UIControlStateNormal];
}
-(void) refreshInvoked:(id)sender forState:(UIControlState)state {
NSOperationQueue *refreshQueue = [[NSOperationQueue alloc] init];
[refreshQueue addOperationWithBlock:^{
[self refreshFeed2];
}];
}
Any help?
Thanks!
Can you try this? replace
[self refreshInvoked:self forState:UIControlStateNormal];
by
[self performSelectorOnBackground:#selector(refreshFeed2) withObject:nil];
and replace the same instead of
-(void) refreshInvoked:(id)sender forState:(UIControlState)state {
[self performSelectorOnBackground:#selector(refreshFeed2) withObject:nil ];
}

AFJSONRequestOperation Crash data parameter is nil

I'm experiencing a strange issue that only happens intermittently when I run my app. I'm attempting to pull down JSON from two different sources, using AFNetworking. Occasionally, when the operations are running, the app will crash with *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil' landing on json_request_operation_processing_queue.
I'm hoping this isn't a problem with AFNetworking, and I'm just doing something incorrectly. Here are my methods that I think are relavent (JSONManager extends AFHTTPClient):
+ (JSONManager *) sharedJSONManager {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedJSONManagerInsance = [[JSONManager alloc] initWithBaseURL:[NSURL URLWithString:sourceUrl1]];
});
return _sharedJSONManagerInsance;
}
- (void) loadOperations {
_sharedJSONManagerInsance.operations = [NSMutableArray arrayWithCapacity:2];
[_sharedJSONManagerInsance.operations addObject:[self fetchJSON:sourceUrl1]];
[_sharedJSONManagerInsance.operations addObject:[self fetchJSON:sourceUrl2]];
}
- (void) executeOperations {
[_sharedJSONManagerInsance loadOperations];
_sharedJSONManagerInsance.fetchedStories = [[NSMutableArray alloc] init];
[self enqueueBatchOfHTTPRequestOperations:operations
progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
NSLog(#"Finished %d of %d", numberOfFinishedOperations, totalNumberOfOperations);
}
completionBlock:^(NSArray *operations) {
[[CoreDataManager sharedManager] persistFetchedStories:_sharedJSONManagerInsance.fetchedStories];
_sharedJSONManagerInsance.operations = nil;
NSLog(#"All operations finished");
}];
}
- (AFHTTPRequestOperation *)fetchJSON:(NSString*)requestUrl {
NSURL* jsonUrl = [NSURL URLWithString:requestUrl];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:jsonUrl];
AFJSONRequestOperation *operation = nil;
operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
if([requestUrl isEqualToString:sourceUrl1]) {
NSArray* arr = [[JSON valueForKeyPath:#"data"] valueForKey:#"children"];
for (NSDictionary *item in arr) {
FetchedStory* fs = [[FetchedStory alloc] init];
fs.title = [[item valueForKey:#"data"]valueForKey:#"title"];
fs.url = [[item valueForKey:#"data"]valueForKey:#"url"];
fs.score = [[item valueForKey:#"data"]valueForKey:#"score"];
fs.source = #"source1";
[self.fetchedStories addObject:fs];
}
}
else if([requestUrl isEqualToString:sourceUrl2]) {
NSArray* arr = [JSON valueForKeyPath:#"items"];
for (NSDictionary *item in arr) {
FetchedStory* fs = [[FetchedStory alloc] init];
fs.title = [item valueForKey:#"title"];
fs.url = [item valueForKey:#"url"];
NSString* scoreString = [item valueForKey:#"score"];
if(scoreString != nil && [scoreString length]!=0) {
NSRange spaceRange = [scoreString rangeOfString:#" "];
scoreString = [scoreString substringToIndex:spaceRange.location];
fs.score = [NSDecimalNumber decimalNumberWithString:scoreString];
fs.source = #"source2";
[self.fetchedStories addObject:fs];
}
}
}
} failure:nil];
return operation;
}
The crash happens before "All operations finished" logs to the console. Again, this only happens some of the time.
It looks like this is a bug with AFJSONRequestOperation's responseJSON method. I added a nil check and that seems to be a good bandaid.
Actually you forget to set HTTP Method Parameter it should be like this:
[request setHTTPMethod:#"get"]; // post, patch ....

App Crashes when ReloadData done for the tableView

I am using the following code to reload my tableView when its done adding all the data to my Mutable Arrays, but the app always crashes
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Spinner Add while waiting
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.frame = CGRectMake(147, 10, 25, 25);
[self.tableView addSubview:spinner];
[spinner startAnimating];
operationQueue = [[NSOperationQueue alloc] init];
usersFirstName = [[NSMutableArray alloc] init];
usersLastName = [[NSMutableArray alloc] init];
usersAvatar = [[NSMutableArray alloc] init];
NSString *urlstring = [NSString stringWithFormat:#"https://www.test.com/scribble/%#/",scribbleId];
NSURL *url = [NSURL URLWithString:urlstring];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON){
users = JSON[#"users_favored"];
if (users.count > 0) {
NSUInteger count = [users count];
for (NSUInteger i =0; i<count; i++) {
NSString *urlString = [NSString stringWithFormat:#"https://www.test.com%#",[users objectAtIndex:i]];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *requestUser = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:requestUser success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON){
if (i == 0) {
usersFirstName = [JSON[#"first_name"] mutableCopy];
usersLastName = [JSON[#"last_name"] mutableCopy];
usersAvatar = [JSON[#"user_avatar"] mutableCopy];
}else{
[usersFirstName addObjectsFromArray:JSON[#"first_name"]];
[usersLastName addObjectsFromArray:JSON[#"last_name"]];
[usersAvatar addObjectsFromArray:JSON[#"user_avatar"]];
}
if (i == count-1) {
[self.tableView reloadData];
[spinner stopAnimating];
[spinner removeFromSuperview];
}
}failure:nil];
[operationQueue addOperation:operation];
}
}else{
self.navigationItem.title = #"No Favors";
[spinner stopAnimating];
[spinner removeFromSuperview];
}
} failure:nil];
[operationQueue addOperation:operation];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return usersFirstName.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableFavorIdentifier = #"FavorCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableFavorIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableFavorIdentifier];
}
NSString *firstName = [usersFirstName objectAtIndex:indexPath.row];
NSString *lastName = [usersLastName objectAtIndex:indexPath.row];
NSString *avatar = [usersAvatar objectAtIndex:indexPath.row];
NSString *userFullName = [NSString stringWithFormat:#"%# %#",firstName,lastName];
UIImageView *userAvatar = (UIImageView *)[cell viewWithTag:100];
if ([avatar length ] > 0) {
NSString *img = [#"https://dtest_media_and_assets.s3.amazonaws.com/" stringByAppendingString:avatar];
[userAvatar setImageWithURL:[NSURL URLWithString:img] placeholderImage:[UIImage imageNamed:#"scribble.png"]];
}else{
userAvatar.image = [UIImage imageNamed:#"scribble.png"];
}
userAvatar.layer.cornerRadius = 4.0;
userAvatar.clipsToBounds = YES;
UILabel *userNameLabel = (UILabel *)[cell viewWithTag:101];
userNameLabel.text = userFullName;
return cell;
}
The error it gives is
2013-03-15 16:37:08.910 test[19547:c07] -[__NSCFString count]: unrecognized selector sent to instance 0x8679c80
2013-03-15 16:37:08.911 test[19547:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString count]: unrecognized selector sent to instance 0x8679c80'
*** First throw call stack:
(0x1cdf012 0x169fe7e 0x1d6a4bd 0x1ccebbc 0x1cce94e 0x143d7 0x7c8548 0x7cb224 0x68f952 0x68f2dc 0x140d7 0x281d2 0x29569 0x2f9553f 0x2fa7014 0x2f977d5 0x1c85af5 0x1c84f44 0x1c84e1b 0x21bb7e3 0x21bb668 0x5e3ffc 0x200d 0x1f35)
libc++abi.dylib: terminate called throwing an exception
Edit
everything works just fine when I use this instead
[usersFirstName addObject:JSON[#"first_name"]];
[usersLastName addObject:JSON[#"last_name"]];
[usersAvatar addObject:JSON[#"user_avatar"]];
[self.tableView reloadData];
if (i == count-1) {
[spinner stopAnimating];
[spinner removeFromSuperview];
}
try the same with that function:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"usersFirstName is of type %#", NSStringFromClass([usersFirstName class]));
return [usersFirstName count];
}
I guess you have to replace:
if (i == 0) {
usersFirstName = [JSON[#"first_name"] mutableCopy];
usersLastName = [JSON[#"last_name"] mutableCopy];
usersAvatar = [JSON[#"user_avatar"] mutableCopy];
}else{
[usersFirstName addObjectsFromArray:JSON[#"first_name"]];
[usersLastName addObjectsFromArray:JSON[#"last_name"]];
[usersAvatar addObjectsFromArray:JSON[#"user_avatar"]];
}
with just:
[usersFirstName addObject:JSON[#"first_name"]];
[usersLastName addObject:JSON[#"last_name"]];
[usersAvatar addObject:JSON[#"user_avatar"]];
The issue is that this:
users = JSON[#"users_favored"];
Returns an NSString, when it looks you are expecting an NSArray.
Verify this using:
users = JSON[#"users_favored"];
NSLog(#"users is of type %#", NSStringFromClass([users class]));
Something is either wrong with your assumption or the JSON is broken.

Resources