AFNetworking tutorial of raywenderlich not displaying data on table cell - ios

I am learning AFNetworking using,
https://www.raywenderlich.com/59255/afnetworking-2-0-tutorial
But, For json part I am not getting data displayed on cell that displyed in this tutorial.
I am getting response in json format but after that nothing is displayed in cells.
static NSString * const BaseURLString = #"http://www.raywenderlich.com/demos/weather_sample/";
#interface WTTableViewController ()
#property(strong) NSDictionary *weather;
#end
#implementation WTTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.toolbarHidden = NO;
[self.tableView setDelegate:self];
self.tableView.dataSource=self;
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"WeatherDetailSegue"]){
UITableViewCell *cell = (UITableViewCell *)sender;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
WeatherAnimationViewController *wac = (WeatherAnimationViewController *)segue.destinationViewController;
NSDictionary *w;
switch (indexPath.section) {
case 0: {
w = self.weather.currentCondition;
break;
}
case 1: {
w = [self.weather upcomingWeather][indexPath.row];
break;
}
default: {
break;
}
}
wac.weatherDictionary = w;
}
}
#pragma mark - Actions
- (IBAction)clear:(id)sender
{
self.title = #"";
self.weather = nil;
[self.tableView reloadData];
}
- (IBAction)jsonTapped:(id)sender
{
NSString *string = [NSString stringWithFormat:#"%#weather.php?format=json", BaseURLString];
NSURL *url = [NSURL URLWithString:string];
//NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:string parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(#"Error: %#", error);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Weather"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(!self.weather)
return 1;
switch (section) {
case 0: {
NSLog(#"return 1");
return 1;
}
case 1: {
NSArray *upcomingWeather = [self.weather upcomingWeather];
NSLog(#"return upcomingWeather");
return [upcomingWeather count];
}
default:
return 0;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{NSLog(#"tableView");
static NSString *CellIdentifier = #"WeatherCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *daysWeather = nil;
switch (indexPath.section) {
case 0: {
daysWeather = [self.weather currentCondition];
NSLog(#"currentCondition");
break;
}
case 1: {
NSArray *upcomingWeather = [self.weather upcomingWeather];
daysWeather = upcomingWeather[indexPath.row];
NSLog(#"upcomingWeather");
break;
}
default:
break;
}
cell.textLabel.text = [daysWeather weatherDescription];
NSLog(#"textLabel = %#", cell.textLabel.text);
// Configure the cell...
return cell;
}
I have this code in my table view controller.
This methods are used in delegate method in above code :
- (NSDictionary *)currentCondition
{
NSDictionary *dict = self[#"data"];
NSArray *ar = dict[#"current_condition"];
return ar[0];
}
- (NSArray *)upcomingWeather
{
NSDictionary *dict = self[#"data"];
return dict[#"weather"];
}
I am getting response in json formate but cells are empty.
Please refer tutorial if anything is missing here.
Thank you.

In success of data received you just printing data.
you have to store that data in dictionary and reload tableview.
Use below code:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:string parameters:nil progress:nil
success:^(NSURLSessionTask *task, id responseObject) {
self.weather = (NSDictionary *)responseObject; //add this line
[self.tableView reloadData]; //add this line
} failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(#"Error: %#", error);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Weather"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];

You are missing following code from success block
self.weather = (NSDictionary *)responseObject;
self.title = #"JSON Retrieved";
[self.tableView reloadData];

Just check the data existence inside weather dict once before you loaded into tableview and after completion of getting data from server just call reloadData method of uitableView so it will load data received by your code later.

Related

Textfields as search bar getting crash

I am using this code for textfiled as search bar.Here is my code. but i am getting crash for range on textfield.if i start entering then its crashing.Even not able to handle case sensitive text also
#import "ViewController.h"
#import "AFNetworking.h"
#import <QuartzCore/QuartzCore.h>
#interface ViewController ()
{
NSMutableArray *countryArray;
NSMutableArray *searchArray;
NSString *searchTextString;
BOOL isFilter;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_countryView.hidden = true;
self->countryArray = [[NSMutableArray alloc] init];
[self makeRestuarantsRequests];
_tableView.layer.borderColor = [UIColor lightGrayColor].CGColor;
_tableView.layer.borderWidth = 1;
_tableView.layer.cornerRadius=5;
[self.searchTextField addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
}
-(void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[[NSNotificationCenter defaultCenter]removeObserver:self
name:UITextFieldTextDidChangeNotification object:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - AFNetworking
-(void)makeRestuarantsRequests{
NSURL *url = [NSURL URLWithString:#"example url"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id responseObject) {
self->countryArray = [responseObject objectForKey:#"data"];
[self.tableView reloadData];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id responseObject) {
NSLog(#"Request Failed with Error: %#, %#", error, error.userInfo);
}];
[operation start];
}
#pragma mark - Tableview Delegate and Datasource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(isFilter)
{
return [searchArray count];
}
else
return [countryArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *tempDictionary= [self->countryArray objectAtIndex:indexPath.row];
if(isFilter)
{
cell.textLabel.text=[searchArray objectAtIndex:indexPath.row];
}
else
{
cell.textLabel.text = [tempDictionary objectForKey:#"name"];
}
// cell.textLabel.text = [tempDictionary objectForKey:#"name"];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[_SelectCountryButton setTitle:cell.textLabel.text forState:UIControlStateNormal];
_countryView.hidden = true;
}
-(void)textFieldDidChange:(UITextField *)textField
{
searchTextString=textField.text;
[self updateSearchArray:searchTextString];
}
-(void)updateSearchArray:(NSString *)searchText
{
if(searchText.length==0)
{
isFilter=NO;
}
else{
isFilter=YES;
searchArray=[[NSMutableArray alloc]init];
for(NSString *string in countryArray){
NSRange stringRange=[string rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringRange.location !=NSNotFound){
[searchArray addObject:string];
}
}
[self.tableView reloadData];}
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
#pragma mark UITextFieldDelegates
- (IBAction)SelectCountry:(id)sender {
_countryView.hidden = false;
}
#end
Getting crash error :
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI rangeOfString:options:]: unrecognized selector sent to instance 0x10128b4f0
error code :
-(void)updateSearchArray:(NSString *)searchText
{
if(searchText.length==0)
{
isFilter=NO;
}
else{
isFilter=YES;
searchArray=[[NSMutableArray alloc]init];
for(NSString *string in countryArray){
NSRange stringRange=[string rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringRange.location !=NSNotFound){
[searchArray addObject:string];
}
}
[self.tableView reloadData];}
}
Please help me out.How can i solve this issues.
Thanks in advance !
UPDATE :
{"response":true,"message":"country.","data":[{"id":1,"name":"Afghanistan"},{"id":2,"name":"Albania"},{"id":3,"name":"Algeria"},{"id":4,"name":"American Samoa"},{"id":5,"name":"Andorra"},{"id":6,"name":"Angola"}]}
well i have good approach with predicate
well according to you jsonResponse
// so forEach loop should like this
for(NSDictionary *Dic in CountryArray){
NSString*str=[NSString stringWithFormat:#"%#",[dic objectForKey:#"name"]];
}
// well i am not using for each loop instead of that i have nsmutablearray name as _searchArraySingle is same like your countryArray with predicate
// if you are using textfield in place of default Searchbar so use this then use NSPredicate
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(textFieldTextDidChangeOneCI:)
name:UITextFieldTextDidChangeNotification
object:searchTxt];
SearchBar.delegate = (id)self;
}
-(void)textFieldTextDidChangeOneCI:(NSNotification *)notification {
UITextField *textfield=[notification object];
[self predicatChangeText:textfield.text];
// NSLog(#"%#",textfield.text);
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
-(void)predicatChangeText:(NSString*)text{
// myJSON.array
NSPredicate *predicateString = [NSPredicate predicateWithFormat:#"%K contains[cd] %#", #"name", text];
_filteredArray = [NSMutableArray arrayWithArray:[_searchArraySingle filteredArrayUsingPredicate:predicateString]];
NSLog(#"_filteredArray=%lu",(unsigned long)[_filteredArray count]);
[self.tableView reloadData];
}
- (IBAction)cancleSearch:(id)sender {
searchTxt.text=#"";
if (_filteredArray) {
_filteredArray=nil;
}
[self.searchTxt resignFirstResponder];
_filteredArray = myJSON.array;
[self.tableView reloadData];
}
Might this will help you out !!!! GoodLuck

ios : UITableView is showing data when i tap on it

Hello i'm creating custom contact view using UITableView. I fetched all contacts and using table relodData but it not showing in table. On a single tap on table then data is visible. In view will appear i'm calling to fetch all contacts in phone and on completion it will reload tableView to make contact visible but it shows if i tap on it or open other view and come back.
#import "CMContatcsVC.h"
#import "CMContatcsTableCell.h"
#implementation CMContatcsVC
//======================================================================================================================================================
#pragma mark - VIEW LIFE CYCLE
//======================================================================================================================================================
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
[self fetchAllContactsCompletionHandler:^(BOOL granted, NSError * _Nullable error) {
[self.tableView reloadData];
NSLog(#"COUNT_IN_COMPLETION_HANDLER :: %lu", (unsigned long)self.contactArray.count);
}];
}
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
//======================================================================================================================================================
#pragma mark - TABLE VIEW DELEGATES METHODS
//======================================================================================================================================================
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"TABLE SECTION");
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"TABLE ROWS :: %lu",(unsigned long)self.contactArray.count);
return self.contactArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"TABLE CELL FPR ROW");
CMContatcsTableCell *contactCell = (CMContatcsTableCell *)[tableView dequeueReusableCellWithIdentifier:#"CMContatcsTableCell" forIndexPath:indexPath];
#try
{
CMCustomContacts * contact = [self.contactArray objectAtIndex:indexPath.row];
[contactCell.profileImgView setImage:contact.profileImage];
[contactCell.nameLabel setText:contact.firstName];
NSLog(#"TABLE CELL CNT NAME :: %#", contact.firstName);
[contactCell.contactLabel setText:[contact.phoneArray objectAtIndex:0]];
}
#catch (NSException *exception)
{
NSLog(#"TABLE CELL EXCEPTION :: %#", exception.description);
}
#finally
{}
return contactCell;
}
//======================================================================================================================================================
#pragma mark - FETCH ALL CONTACTS
//======================================================================================================================================================
-(void)fetchAllContactsCompletionHandler:(void(^)(BOOL granted, NSError * _Nullable error))completion
{
self.contactArray = [[NSMutableArray alloc] init];
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted)
{
NSArray *keys = #[CNContactNamePrefixKey, CNContactFamilyNameKey, CNContactGivenNameKey,
CNContactPhoneNumbersKey, CNContactImageDataKey, CNContactEmailAddressesKey];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
if (error)
{
NSLog(#"ERROR IN FETCHING CONTACTS :: %#", error.description);
}
else
{
for (CNContact *contact in cnContacts)
{
#try
{
CMCustomContacts *newContact = [[CMCustomContacts alloc] init];
newContact.phoneArray = [[NSMutableArray alloc] init];
newContact.emailArray = [[NSMutableArray alloc] init];
newContact.firstName = contact.givenName;
newContact.lastName = contact.familyName;
UIImage *image = [UIImage imageWithData:contact.imageData];
newContact.profileImage = image;
for (CNLabeledValue *label in contact.phoneNumbers)
{
NSString *phone = [label.value stringValue];
if ([phone length] > 0)
{
[newContact.phoneArray addObject:phone]; NSLog(#"PHONE :: %#",phone);
}
}
for (CNLabeledValue *label in contact.emailAddresses)
{
NSString *email = label.value;
if ([email length] > 0)
{
[newContact.emailArray addObject:email]; NSLog(#"EMAIL :: %#",email);
}
}
[self.contactArray addObject:newContact];
}
#catch (NSException *exception)
{
NSLog(#"EXCEPTION IN CONTACTS :: %#", exception.description);
}
#finally
{
NSLog(#"FINALLY");
}
}
NSLog(#"COUNT OF CONTACTS :: %lu", (unsigned long)self.contactArray.count);
}
}
completion(granted, error);
}];
}
#end
Always update your UI on main thread, so call reloadData of TableView on main thread like this.
[self fetchAllContactsCompletionHandler:^(BOOL granted, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
}
NSLog(#"COUNT_IN_COMPLETION_HANDLER :: %lu", (unsigned long)self.contactArray.count);
}];

Tableview is not showing cells in the time i posted

I have created a app that fetches information from a blog and shows it in the app. After i fetch the data it is supposed to be shown on the table view. It shows the things that i have posted but the things are in alphabetical order rather than the time i posted the thing.
Here is the code
#implementation EventsTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.firstLettersArray = [NSMutableArray array];
self.eventsDictionary = [NSMutableDictionary dictionary];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self searchForEvents];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self searchForEvents];
}
- (void)searchForEvents
{
[self.searchBar resignFirstResponder];
NSString *eventsSearchUrlString = [NSString stringWithFormat:#"https://www.googleapis.com/blogger/v3/blogs/1562818803553764290/posts?key=AIzaSyBTOxz-vPHgzIkw9k88hDKd99ILTaXTt0Y"];
NSURL *eventsSearchUrl = [NSURL URLWithString:eventsSearchUrlString];
NSURLRequest *eventsSearchUrlRequest = [NSURLRequest requestWithURL:eventsSearchUrl];
NSURLSession *sharedUrlSession = [NSURLSession sharedSession];
NSURLSessionDataTask *searchEventsTask =
[sharedUrlSession dataTaskWithRequest:eventsSearchUrlRequest completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error)
{
dispatch_async(dispatch_get_main_queue(),
^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
if(error)
{
UIAlertView *searchAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:error.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[searchAlertView show];
}
else
{
NSString *resultString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Search results: %#", resultString);
NSError *jsonParseError = nil;
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonParseError];
if(jsonParseError)
{
UIAlertView *jsonParseErrorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:jsonParseError.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[jsonParseErrorAlert show];
}
else
{
for(NSString *key in jsonDictionary.keyEnumerator)
{
NSLog(#"First level key: %#", key);
}
[self.firstLettersArray removeAllObjects];
[self.eventsDictionary removeAllObjects];
NSArray *searchResultsArray = [jsonDictionary objectForKey:#"items"];
//NSLog(#"test%#",searchResultsArray);
for(NSDictionary *eventsInfoDictionary in searchResultsArray)
{
Events *event = [[Events alloc] init];
event.eventName = [eventsInfoDictionary objectForKey:#"title"];
event.eventDescription =[eventsInfoDictionary objectForKey:#"content"];
NSLog(#"Event Name : %#",event.eventName);
NSLog(#"Event Description : %#",event.eventDescription);
NSString *eventsFirstLetter = [event.eventName substringToIndex:1];
NSMutableArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:eventsFirstLetter];
if(!eventsWithFirstLetter)
{
eventsWithFirstLetter = [NSMutableArray array];
[self.firstLettersArray addObject:eventsFirstLetter];
}
[eventsWithFirstLetter addObject:event];
[self.eventsDictionary setObject:eventsWithFirstLetter forKey:eventsFirstLetter];
if ([event.eventDescription containsString:#"<br />"]) {
NSString* eventDescrip = event.eventDescription;
NSString* stringWithoutHTMLtags = [eventDescrip stringByReplacingOccurrencesOfString:#"<br />" withString:#""];
event.eventDescription = stringWithoutHTMLtags;
}
NSLog(#"Event Name : %#",event.eventName);
NSLog(#"Event Description : %#",event.eventDescription);
}
[self.firstLettersArray sortUsingSelector:#selector(compare:)];
[self.tableView reloadData];
}
}
});
}];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[searchEventsTask resume];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.firstLettersArray.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *firstLetter = [self.firstLettersArray objectAtIndex:section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
return eventsWithFirstLetter.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"eventTitleCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *firstLetter = [self.firstLettersArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
Events *event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
cell.textLabel.text = event.eventName;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
/*
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
NSLog(#"Row selected %#",cellText);*/
NSString *firstLetter = [self.firstLettersArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
Events *event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
DescriptionViewController *descriptionViewController = (DescriptionViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: #"descriptionController"];
descriptionViewController.eventNameDesc = event.eventDescription;
descriptionViewController.navigationItem.title = event.eventName;
[self.navigationController pushViewController:descriptionViewController animated:YES];
}
#end
You are trying to sort firstLettersArray which contain Events objects by using standard sort: function which doesn't know how to work with your custom objects.
You can use sortedArrayUsingComparator: function like this:
[firstLettersArray sortedArrayUsingComparator:^NSComparisonResult(Events *obj1, Events *obj2) {
// return object comparison result here
}];
Edit: Also you need to have NSDate property in Events class and feel it with event created time. I believe event created time should be contained in eventsInfoDictionary. Eventually you will be able to compare obj1 and obj2 using NSDate property.
i think this line not working
[self.firstLettersArray sortUsingSelector:#selector(compare:)];
use this line of code may help you....
sortedArray = [anArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];

Implementing pagination in UITableView with scrollViewDidScroll method?

I’m building an article reading app.I’m using AFNetworking third party library to fetch JSON data into the UITableView.
Let say Json link is www.example.com&page=1 gives 1-10 articles and www.example.com&page=2 gives11-20 articles and so on.
I have implemented pagination and scrollViewDidScroll method means when user scroll it gives next ten article.
I’m facing an issue when app launch and UITableView load scrollViewDidScroll method called three times but expected call once.
I’m using increment variable for pagination in scrollViewDidScroll method as i say it call three time and x value goes to 3 and give 30 articles.
When user scroll again it gives next 30 articles.i’m unable to figure out why scrollViewDidScroll method called three times when app is launched.
this is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
tempJson = [[NSMutableArray alloc] init];
[self loadNinjas];
}
- (void)loadNinjas {
NSString *jsonLink=[NSString stringWithFormat:#"www.example.com&page=%d",x];
NSURL *url = [[NSURL alloc] initWithString:jsonLink];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSArray *jsonArray = (NSArray *)responseObject;
for (NSDictionary *dic in jsonArray) {
Json *json = [[Json alloc] initWithDictionary:dic];
[tempJson addObject:json];
}
self.jsons = [[NSArray alloc] initWithArray:tempJson];
[self.tableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
[operation start];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.jsons.count ;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Cellidentifier1 = #"ysTableViewCell";
ysTableViewCell *cell1 = [tableView
dequeueReusableCellWithIdentifier:Cellidentifier1 forIndexPath:indexPath];
cell1.TitleLabel1.text = [self.jsons[indexPath.row] title];
cell1.AuthorLabel1.text = [self.jsons[indexPath.row] author];
[cell1.ThumbImage1 setImageWithURL:[NSURL URLWithString:
[self.jsons[indexPath.row] a_image]]];
return cell1;}
- (void)scrollViewDidScroll: (UIScrollView*)scroll {
CGFloat currentOffset = scroll.contentOffset.y;
CGFloat maximumOffset = scroll.contentSize.height - scroll.frame.size.height;
self.tableView.contentInset = UIEdgeInsetsMake(65, 0, 0, 0);
if (maximumOffset - currentOffset <= -60.0) {
x++;
[self loadNinjas];
[self.tableView addInfiniteScrollingWithActionHandler:^{
}];
[self.tableView reloadData];
}
}
This is a simple code that initializes the tableView with 50 cells and as the user scrolls down the page, adds 20 new cells to the tableView every time it reaches the cell which is 10 cells above the end of the table.
int i;
int lastSeen;
- (void)viewDidLoad {
[super viewDidLoad];
i = 50;
lastSeen = 0;
}
#pragma mark - Table view data source
- (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 i;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%ld", (long)indexPath.row];
lastSeen = (lastSeen < indexPath.row) ? indexPath.row : lastSeen;
return cell;
}
- (void)scrollViewDidScroll: (UIScrollView*)scroll {
if (lastSeen >= (i - 10)) {
i += 20;
//load new data here.
[self.tableView reloadData];
}
}

Table View and AFNetworking Asynchronous Call

I'm new to iOS development and I am trying to figure out what the best solution to my problem would be. I have a UITableViewController class which calls a method named fetchModules in the viewDidLoad. This fetches all the data I need for my table using AFNetworking 2.
However, my table delegate methods such as numberOfRowsInSectionand cellForRowAtIndexPath are failing because the AFNetworking call has not finished yet and the array I am using to store the data has not been populated.
The actual error I am getting is
Terminating app due to uncaught exception 'NSRangeException'
Here's my code:
#import "HistoryTableViewController.h"
#interface HistoryTableViewController ()
#property NSArray *modules;
#end
#implementation HistoryTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.modules = [[NSArray alloc] init];
[self fetchModules];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)fetchModules
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setValue:self.token forHTTPHeaderField:#"X-Auth-Token"];
[manager GET:#"http://myurl.com/" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
//NSLog(#"JSON: %#", responseObject);
self.modules = [responseObject objectForKey:#"data"];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.modules && self.modules.count) {
return self.modules.count;
} else {
return 0;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"Cell Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
}
NSDictionary *module = [self.modules objectAtIndex:indexPath.row];
cell.textLabel.text = [module objectForKey:#"code"];
return cell;
}
Suggestions?
It's pretty much common solution for async network call.
Add [self.tableView reloadData] inside the AFNetworking success block:
- (void)fetchModules
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setValue:self.token forHTTPHeaderField:#"X-Auth-Token"];
[manager GET:#"http://myurl.com/" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
//NSLog(#"JSON: %#", responseObject);
self.modules = [responseObject objectForKey:#"data"];
[self.tableView reloadData];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}`enter code here`
I think the conditions should be as below.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.modules != nil && self.modules.count > 0) {
return self.modules.count;
} else {
return 0;
}
}
Also do not forget to reload table after you get the response.
Few corrections may help you. First synthesize property "modules". Also in delegate method for creating Table Cell ensure that if "modules" is empty then that method should do no operation on "modules" property and just return "cell". I hope this helps you

Resources