How to add Pagination to Tableview on Search results? - objective-c

The following lines of code shown below are my current tableview settings. What i would like to achieve is what's seen on the image below.
1) if count is 4 when user scrolls Down show a Activity Indicator and Make a request using the next value shown on the JSON Below.
2) Reload the Table
3) Show No more results if count is empty.
Note: I am new on Objective-C so I will appreciate your guidance on this subject since all searches I have done were not successful on what I am looking to achieve since all of them are based on a table already loaded and not based on a Search Result.
As shown on the Image Below is a reference what i want to achieve.
JSON RESPONSE FROM SEARCH
{
"count": 4,
"next": "http://api.domain.com/user-search/?page=2&subject=culture",
"previous": null,
"results": [
{
"name": "Guillermo Davila",
"nick": "guillermo",
"avatar_s": "https://pbs.twimg.com/profile_images/2213685686/image.jpg",
"user_rate": "$10/h",
"id": 3,
"subjects": "Culture and 1 other subject",
"bio": "I'm a nice person"
},
{
"name": "Frank Smith",
"nick": "fsmith",
"avatar_s": "https://pbs.twimg.com/profile_images/2444486/image.jpg",
"user_rate": "$14/h",
"id": 3,
"subjects": "Culture and 1 other subject",
"bio": "I'm a nice person 2"
}
]
}
And here is my UserTableviewController.h
//
// UserTableViewController.m
// mobile-app
//
// Created by eddwinpaz on 5/18/14.
// Copyright (c) 2014 eddwinpaz. All rights reserved.
//
#import "UserTableViewController.h"
#import "CustomTableCell.h"
#import "UserDetailViewController.h"
#import "AFNetworking.h"
#import "MBProgressHUD.h"
#import "SimpleAudioPlayer.h"
#interface UserTableViewController ()
#end
#implementation UserTableViewController
{
// JSON Request
NSMutableArray *myObject;
// A Dictionary Object
NSDictionary *dictionary;
NSString *name;
NSString *subject;
NSString *avatar;
NSString *rate;
NSString *bio;
NSString *nick;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//[self fetch_tutors]; // Get tutors Ordered By Karma DESC
// 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.
}
#pragma mark - Table view data source
/*
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 0;
} */
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return myObject.count; // This is old 100% working code
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomTableCell";
CustomTableCell *cell = (CustomTableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
dictionary = [myObject objectAtIndex:indexPath.row];
cell.labelName.text = [dictionary objectForKey:#"name"];
cell.labelBio.text = [dictionary objectForKey:#"bio"];
cell.labelSubjects.text = [dictionary objectForKey:#"subject"];
cell.imageAvatar.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[dictionary objectForKey:#"avatar"]]]];
cell.imageAvatar.clipsToBounds = YES;
cell.imageAvatar.layer.cornerRadius = cell.imageAvatar.frame.size.width / 2;
cell.labelRate.text = [dictionary objectForKey:#"rate"];
cell.labelRate.layer.cornerRadius = 5;
[SimpleAudioPlayer playFile:#"upvote.wav"];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showUserDetail"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UserDetailViewController *destViewController = segue.destinationViewController;
NSDictionary *dict = [myObject objectAtIndex:indexPath.row];
destViewController.http_nick = [dict valueForKey:#"nick"];
destViewController.labelName = [dict valueForKey:#"name"];
NSLog(#" Username Sent--->%#", [dict valueForKey:#"nick"]);
NSLog(#" name Sent--->%#", [dict valueForKey:#"name"]);
}
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
NSString *searchTerm = searchBar.text;
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.mode = MBProgressHUDModeIndeterminate;
hud.labelText = #"Searching Tutors";
[hud show:YES];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *url = [NSString stringWithFormat:#"http://api.domain.com/user-search/?subject=%#",searchTerm];
[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
[hud hide:YES];
int count_total = [[responseObject objectForKey:#"count"] intValue];
if (count_total == 0) {
[myObject removeAllObjects];
NSLog(#"Count is --->0");
}
else {
myObject = [[NSMutableArray alloc] init];
name = #"name";
subject = #"subject";
avatar = #"avatar";
rate = #"rate";
bio = #"bio";
nick = #"nick";
for (NSDictionary *dataDict in [responseObject objectForKey:#"results"])
{
NSString *name_data = [dataDict objectForKey:#"name"];
NSString *subject_data = [dataDict objectForKey:#"subjects"];
NSString *avatar_data = [dataDict objectForKey:#"avatar_s"];
NSString *rate_data = [dataDict objectForKey:#"user_rate"];
NSString *bio_data = [dataDict objectForKey:#"bio"];
NSString *nick_data = [dataDict objectForKey:#"nick"];
NSLog(#"name: %#", name_data);
NSLog(#"subjects: %#",subject_data);
NSLog(#"avatar_s: %#", avatar_data);
NSLog(#"user_rate: %#",rate_data);
NSLog(#"bio: %#",bio_data);
NSLog(#"nick: %#",nick_data);
dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
name_data,name,
subject_data,subject,
avatar_data,avatar,
rate_data,rate,
bio_data, bio,
nick_data, nick, nil];
[myObject addObject:dictionary];
}
}
[self.searchBar endEditing:YES];
[self.searchBar setShowsCancelButton:NO animated:YES];
[self.searchBar sizeToFit];
[self.tableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
[hud hide:YES];
}];
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
[searchBar sizeToFit];
[searchBar setShowsCancelButton:YES animated:YES];
return YES;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[self.searchBar endEditing:YES];
[searchBar setShowsCancelButton:NO animated:YES];
self.searchBar.text = nil;
}
/*
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"userDetailView"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UserDetailViewController *destViewController = segue.destinationViewController;
destViewController.labelName = [myObject objectAtIndex:indexPath.row];
}
} */
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end

One way to achieve it is,
Return the numberOfCells as one more than the data array
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return myDataArray +1 ; //myDataArray is the data and One more cell for the last cell (10 out of 46 results cell)
}
In cellForRowAtIndexPath, if your IndexPath.row == myDataArray.count (ie., Last Row) Create a custom cell which looks as in the picture and return the custom cell.
In - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath, If the indexPath corresponds to last cell, then Start Request for page 2, once the results are fetched, update the myDataArray and reload the table.

Related

Search bar in tableview using objective c with parse database

I've been following a tutorial teaching how to make a tableview with a search bar. I got this to work without problems, but now I learned to make the same tableview but instead of local arrays, I've been getting my data from parse as PFObjects.
I then tried to take the search bar and implant it in my new tableview which uses parse. I can't get this to work. Following the tutorial with the search bar they are using simple arrays stored locally..
Can anyone point me in the right direction of how to use a search bar in a tableview that gets its data from a parse database?
This is my code that works with my tableview that does NOT use parse.
#implementation RecipeBookViewController {
NSArray *recipes;
NSArray *searchResults;
}
#synthesize tableView = _tableView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize table data
recipes = [NSArray arrayWithObjects:#"Egg Benedict", #"Mushroom Risotto",
#"Full Breakfast", #"Hamburger", #"Ham and Egg Sandwich", #"Creme Brelee",
nil];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [recipes count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"RecipeCell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [recipes objectAtIndex:indexPath.row];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath
- *)indexPath
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
[self performSegueWithIdentifier: #"showRecipeDetail" sender: self];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
RecipeDetailViewController *destViewController =
segue.destinationViewController;
NSIndexPath *indexPath = nil;
if ([self.searchDisplayController isActive]) {
indexPath = [self.searchDisplayController.searchResultsTableView
indexPathForSelectedRow];
destViewController.recipeName = [searchResults
objectAtIndex:indexPath.row];
} else {
indexPath = [self.tableView indexPathForSelectedRow];
destViewController.recipeName = [recipes objectAtIndex:indexPath.row];
}
}
}
- (void)filterContentForSearchText:(NSString*)searchText scope:
(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
searchResults = [recipes filteredArrayUsingPredicate:resultPredicate];
}
#pragma mark - UISearchDisplayController delegate methods
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar
scopeButtonTitles]
objectAtIndex:
[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
And this is my tableview which get its data from my parse database:
#implementation RecipeBookViewController {
}
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"Recipe";
// The key of the PFObject to display in the label of the default cell
style
self.textKey = #"name";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = NO;
// The number of objects to show per page
//self.objectsPerPage = 10;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(refreshTable:)
name:#"refreshTable"
object:nil];
}
- (void)refreshTable:(NSNotification *) notification
{
// Reload the recipes
[self loadObjects];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"refreshTable"
object:nil];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (PFQuery *)queryForTable
{
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
// If no objects are loaded in memory, we look to the cache first
to fill the table
// and then subsequently do a query against the network.
/* if ([self.objects count] == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}*/
// [query orderByAscending:#"name"];
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:
(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
PFFile *thumbnail = [object objectForKey:#"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:#"placeholder.jpg"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"name"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"prepTime"];
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:
(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath*) indexPath
{
// Remove the row from data model
PFObject *object = [self.objects objectAtIndex:indexPath.row];
[object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
[self refreshTable:nil];
}];
}
- (void) objectsDidLoad:(NSError *)error
{
[super objectsDidLoad:error];
NSLog(#"error: %#", [error localizedDescription]);
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController =
segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
Recipe *recipe = [[Recipe alloc] init];
recipe.name = [object objectForKey:#"name"];
recipe.imageFile = [object objectForKey:#"imageFile"];
recipe.prepTime = [object objectForKey:#"prepTime"];
recipe.ingredients = [object objectForKey:#"ingredients"];
destViewController.recipe = recipe;
}
}

Parse search table not returning correct results

I am using parse as back-end for my app. I have found a few different methods to implement searchbar feature using a Parse tableview. This idea I found from Parse archives shows all objects on initial view and refresh, but when I search it does not return the correct results. If I type one letter "a" it returns some objects containing "a" but if I type more letters or and actual word that I know should be found it returns a blank table. It is also giving a warning when searching: A long-running Parse operation is being executed on the main thread. I have been working and researching this for a few weeks and can't get past this point. See code for implementation file.
#import "RecipeBookViewController.h"
#import "SearchedResultCell.h"
#import "RecipeDetailViewController.h"
#import "HotelViewController.h"
#import "Recipe.h"
static NSString *const NothingFoundCellIdentifier = #"NothingFoundCell";
#interface RecipeBookViewController ()
#end
#implementation RecipeBookViewController {
}
#synthesize searchedBar;
#synthesize searchResults;
#synthesize recipesTable;
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"Recipe";
// The key of the PFObject to display in the label of the default cell style
self.textKey = #"name";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = NO;
// The number of objects to show per page
//self.objectsPerPage = 10;
}
return self;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - UIViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UINib *cellNib = [UINib nibWithNibName:NothingFoundCellIdentifier bundle:nil];
[self.tableView registerNib:cellNib forCellReuseIdentifier:NothingFoundCellIdentifier];
[self.searchedBar becomeFirstResponder];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(refreshTable:)
name:#"refreshTable"
object:nil];
}
- (void)refreshTable:(NSNotification *) notification
{
// Reload the recipes
[self loadObjects];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"refreshTable" object:nil];
}
#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchResults removeAllObjects];
[self.searchedBar resignFirstResponder];
searchResults = [NSMutableArray arrayWithCapacity:10];
//#warning Put your ClassName here
PFQuery *query = [PFQuery queryWithClassName:#"Recipe"];
//#warning put key that you want to search here
[query whereKey:#"name" containsString:searchedBar.text];
NSArray *results = [query findObjects];
[searchResults addObjectsFromArray:results];
//#warning put your key here
[query orderByAscending:#"name"];
//[self queryForTable];
[self loadObjects];
}
#pragma mark - PFQueryTableViewController
- (void)objectsWillLoad {
[super objectsWillLoad];
// This method is called before a PFQuery is fired to get more objects
}
- (void) objectsDidLoad:(NSError *)error
{
[super objectsDidLoad:error];
NSLog(#"error: %#", [error localizedDescription]);
}
#pragma mark - Query
- (PFQuery *)queryForTable
{
PFQuery *query;
if (self.searchResults == 0) {
query = [PFQuery queryWithClassName:self.parseClassName];
} else {
query = [PFQuery queryWithClassName:self.parseClassName];
NSString *searchThis = [searchedBar.text lowercaseString];
//#warning key you wanted to search here
[query whereKeyExists:#"name"];
[query whereKey:#"name" containsString:searchThis];
}
[query orderByAscending:#"name"];
// If Pull To Refresh is enabled, query against the network by default.
if (self.pullToRefreshEnabled) {
query.cachePolicy = kPFCachePolicyNetworkOnly;
}
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
if (self.objects.count == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
return query;
}
/*
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
if (searchResults == nil) {
return 0;
} else if ([searchResults count] == 0) {
return 1;
} else {
return [self.objects count];
}
}
*/
// Override to customize the look of a cell representing an object. The default is to display
// a UITableViewCellStyleDefault style cell with the label being the first key in the object.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
PFFile *thumbnail = [object objectForKey:#"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:#"recipeBoxImage2.jpg"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"name"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"prepTime"];
static NSString *LoadMoreCellIdentifier = #"LoadMoreCell";
UITableViewCell *loadcell = [self.tableView dequeueReusableCellWithIdentifier:LoadMoreCellIdentifier];
if (!cell) {
loadcell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:LoadMoreCellIdentifier];
}
return cell;
}
- (void)configureSearchResult:(SearchedResultCell *)cell atIndexPath: (NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
SearchedResultCell *searchcell = [self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (searchcell == nil) {
searchcell = [[SearchedResultCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
PFFile *thumbnail = [object objectForKey:#"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:#"recipeBoxImage2.jpg"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"name"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"prepTime"];
}
// Set CellForRowAtIndexPath
- (UITableViewCell *)searchtableView:(UITableView *)searchtableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *CellIdentifier = #"SearchResultCell";
//Custom Cell
SearchedResultCell *cell = [searchtableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[SearchedResultCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([searchResults count] == 0) {
//cell.mainTitle.text = #"Nothing Found";
return [self.tableView dequeueReusableCellWithIdentifier:NothingFoundCellIdentifier];
} else {
//#warning put your ClassName here
PFObject *object = [PFObject objectWithClassName:#"Recipe"];
object = [searchResults objectAtIndex:indexPath.row];
[self configureSearchResult:cell atIndexPath:indexPath object:object];
//[self configureSearchResult:cell atIndexPath:indexPath object:object];
return cell;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForNextPageAtIndexPath:(NSIndexPath *)indexPath {
static NSString *LoadMoreCellIdentifier = #"LoadMoreCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:LoadMoreCellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:LoadMoreCellIdentifier];
}
return cell;
}
//// Set TableView Height for Load Next Page
//- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath {
// if([self.objects count] == indexPath.row) {
// // Load More Cell Height
// return 60.0;
// } else {
// return 80.0;
// }
//}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[searchedBar resignFirstResponder];
if ([self.objects count] == indexPath.row) {
[self loadNextPage];
} else {
PFObject *photo = [self.objects objectAtIndex:indexPath.row];
NSLog(#"%#", photo);
// Do something you want after selected the cell
}
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.searchedBar resignFirstResponder];
}
//- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
//{
// // Remove the row from data model
// PFObject *object = [self.objects objectAtIndex:indexPath.row];
// [object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// [self refreshTable:nil];
// }];
//}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
Recipe *recipe = [[Recipe alloc] init];
recipe.name = [object objectForKey:#"name"];
recipe.imageFile = [object objectForKey:#"imageFile"];
recipe.prepTime = [object objectForKey:#"prepTime"];
recipe.ingredients = [object objectForKey:#"ingredients"];
recipe.instructions = [object objectForKey:#"instructions"];
recipe.servings = [object objectForKey:#"servings"];
recipe.hotelSite = [object objectForKey:#"hotelSite"];
recipe.recipeType = [object objectForKey:#"recipeType"];
destViewController.recipe = recipe;
}
}
#end
found this - hope it helps others - credit to Bizzi-Body
https://github.com/Bizzi-Body/ParseTutorial-Part-2
//
// GourmetChefViewController.m
//
// Created by RedMac on 3/19/15.
//
#import "RecipeBookViewController.h"
#interface RecipeBookViewController ()
{
NSMutableArray *totalStrings;
NSMutableArray *filteredStrings;
BOOL isFiltered;
}
#end
#implementation RecipeBookViewController
#pragma mark -
#pragma mark UIViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
self.mySearchBar.delegate =self;
self.myTableView.delegate = self;
self.myTableView.dataSource=self;
[self retrieveFromParse];
}
- (void) retrieveFromParse {
PFQuery *retrieveRecipes = [PFQuery queryWithClassName:#"Recipe"];
[retrieveRecipes whereKeyExists:#"name"];
[retrieveRecipes findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(#"%#", objects);
totalStrings = [[NSMutableArray alloc] initWithArray:objects];
}
[self.myTableView reloadData];
}];
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *) searchText{
if (searchText.length ==0){
isFiltered =NO;}
else{
isFiltered =YES;
filteredStrings=[[NSMutableArray alloc]init];
for(PFObject *element in totalStrings) {
NSString * str = [element objectForKey:#"name"];
NSLog(#"%#", NSStringFromClass([element class])); // you thought that totalStrings
// contained NSString objects,
// but it contains PFObjects.
NSRange stringRange =[str rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (stringRange.location !=NSNotFound) {
// you need to add the PFObject back to make your cellForRowAtIndexPath: method
// work.
[filteredStrings addObject:element]; // used to be :str
}
}
}
[self.myTableView reloadData];
}
//table view datasource and delegate method.....
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section
{
if (isFiltered){
return [filteredStrings count];
}return [totalStrings count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"RecipeCell";
UITableViewCell *cell= [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (!cell){
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if(!isFiltered){
PFObject *tempObject =[totalStrings objectAtIndex: indexPath.row];
cell.textLabel.text = [tempObject objectForKey:#"name"];
}
else
{
PFObject *tempObject2 =[filteredStrings objectAtIndex: indexPath.row];
cell.textLabel.text =[tempObject2 objectForKey:#"name"];
}
return cell;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end

Problems Implementing Search Bar with Parse Data

I have searched the land of Google far and wide and I have found tutorials on this, but they are before IOS8. I have tried to piece this together as best as I can, but yet when the app runs, and I type words into the search bar, nothing returns, or it crashes. So here's how the view looks, and what each object means:
Here is my JobListViewController.m File:
#import "JobDetailViewController.h"
#import "JobListViewController.h"
#import "Job.h"
#import "SearchedResultCell.h"
#interface JobListViewController () <UISearchDisplayDelegate, UISearchBarDelegate> {
}
#property (nonatomic, weak) IBOutlet UISearchBar *searchedBar;
#property (nonatomic, strong) NSString *mainTitle;
#property (nonatomic, strong) NSString *subTitle;
#property (nonatomic, assign) BOOL canSearch;
#end
#interface JobListViewController ()
#end
#implementation JobListViewController
{
NSArray *jobs;
NSArray *searchResults;
}
#synthesize searchedBar;
#synthesize mainTitle;
#synthesize subTitle;
#synthesize canSearch;
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"Jobs";
// The key of the PFObject to display in the label of the default cell style
self.textKey = #"Position";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = YES;
// The number of objects to show per page
self.objectsPerPage = 10;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.searchedBar becomeFirstResponder];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.canSearch = 0;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)objectsWillLoad {
[super objectsWillLoad];
// This method is called before a PFQuery is fired to get more objects
}
- (PFQuery *)queryForTable
{
PFQuery *query;
if (self.canSearch == 0)
{
query = [PFQuery queryWithClassName:#"Jobs"];
}
else
{
query = [PFQuery queryWithClassName:#"Jobs"];
NSString *searchThis = [searchedBar.text uppercaseString];
[query whereKey:#"Position" containsString:searchThis];
}
[query orderByAscending:#"Position"];
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object: (PFObject *)object
{
static NSString *simpleTableIdentifier = #"JobCell";
static NSString *pimpleTableIdentifier = #"JobCell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
SearchedResultCell *cell = [self.tableView dequeueReusableCellWithIdentifier:pimpleTableIdentifier];
if (cell == nil) {
cell = [[SearchedResultCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:pimpleTableIdentifier];
}
[self configureSearchResult:cell atIndexPath:indexPath object:object];
}
// Configure the cell
PFFile *thumbnail = [object objectForKey:#"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:#"placeholder.jpg"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
UILabel *positionLabel = (UILabel*) [cell viewWithTag:101];
positionLabel.text = [object objectForKey:#"Position"];
UILabel *rotationLabel = (UILabel*) [cell viewWithTag:102];
rotationLabel.text = [object objectForKey:#"Rotation"];
UILabel *locationLabel = (UILabel*) [cell viewWithTag:103];
locationLabel.text = [object objectForKey:#"Location"];
UILabel *typeLabel = (UILabel*) [cell viewWithTag:104];
typeLabel.text = [object objectForKey:#"Type"];
return cell;
}
- (void) objectsDidLoad:(NSError *)error
{
[super objectsDidLoad:error];
NSLog(#"error: %#", [error localizedDescription]);
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showJobDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Job *job = [[Job alloc] init];
JobDetailViewController *destViewController = segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
job.position = [object objectForKey:#"Position"];
job.name = [object objectForKey:#"Name"];
job.email = [object objectForKey:#"Email"];
job.phone = [object objectForKey:#"Phone"];
job.imageFile = [object objectForKey:#"imageFile"];
job.rotation = [object objectForKey:#"Rotation"];
job.location = [object objectForKey:#"Location"];
job.type = [object objectForKey:#"Type"];
job.clearance = [object objectForKey:#"Clearance"];
job.job_description = [object objectForKey:#"Job_Description"];
job.qualifications = [object objectForKey:#"Qualifications"];
destViewController.job = job;
}
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self clear];
self.canSearch = 1;
[self.searchedBar resignFirstResponder];
[self queryForTable];
[self loadObjects];
}
/*
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (searchResults == nil) {
return 0;
} else if ([searchResults count] == 0) {
return 1;
} else {
return [self.objects count];
}
}
*/
- (void)configureSearchResult:(SearchedResultCell *)cell atIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
mainTitle = [object objectForKey:#"Position"];
cell.mainTitle.text = mainTitle;
subTitle = [object objectForKey:#"Type"];
cell.detail.text = subTitle;
// Implement this if you want to Show image
cell.showImage.image = [UIImage imageNamed:#"placeholder.jpg"];
PFFile *imageFile = [object objectForKey:#"imageFile"];
if (imageFile) {
cell.showImage.file = imageFile;
[cell.showImage loadInBackground];
}
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[searchedBar resignFirstResponder];
if ([self.objects count] == indexPath.row) {
[self loadNextPage];
} else {
PFObject *photo = [self.objects objectAtIndex:indexPath.row];
NSLog(#"%#", photo);
// Do something you want after selected the cell
}
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.searchedBar resignFirstResponder];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar {
[self.searchedBar resignFirstResponder];
[self queryForTable];
[self loadObjects];
}
#end
I cannot find where I am going wrong. Any help whatsoever would be much appreciated. Or if anything if you can point me in the right direction.
I had problems with that I few months ago, so below is a project that reeeally helped me. Hope for you too.
https://github.com/mwazir2/ParseSearchNoPagination
cheers!
Update
In my adaptation of this example above I followed everything from the project. The project uses PFQueryTableViewController from Parse SDK and not the default iOS TableViewController.
In the first part -(id)initWithCoder I have commented the
//self.textKey = #"username";
Then I altered the - (PFQuery *)queryForTable method in some ways. One just changed the whereKey to adequate my project and the second changed the query a little bit more because it should only show in the table objects related to specific users. Below follows respective queries.
The first more general query
- (PFQuery *)queryForTable
{
PFQuery *query = [PFUser query];
if (self.canSearch == 0) {
query = [PFQuery queryWithClassName:#"_User"];
} else {
query = [PFQuery queryWithClassName:#"_User"];
NSString *searchThis = [searchedBar.text capitalizedString];
//PFQuery *query = [PFQuery queryWithClassName:#"Channel"];
//[query whereKey:#"channelName" equalTo:searchThis];
[query whereKey:#"username" containsString:searchThis];
}
The second, specific to current user:
- (PFQuery *)queryForTable
{
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
[query whereKey:#"owner" equalTo:[PFUser currentUser]];
[query orderByDescending:#"createdAt"];
if (self.pullToRefreshEnabled) {
query.cachePolicy = kPFCachePolicyNetworkOnly;
}
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
if (self.objects.count == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
return query;
}
For the tableView methods I only used: tableView cellForRowAtIndexPath(pretty much like yours). And also the cellForRowAtIndexPath for the LoadMoreCell, like in the example.
Also the tableView heightForRowAtIndexPath: for the LoadMoreCell and tableView didSelectRowAtIndexPath, like below:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
//[searchedBar resignFirstResponder];
if ([self.objects count] == indexPath.row) {
[self loadNextPage];
} else {
PFObject *photo = [self.objects objectAtIndex:indexPath.row];
NSLog(#"%#", photo);
// Do something you want after selected the cell
}
}
Of course below the } else { statement you can change it or delete the NSLog line.
I suggest you try to alter the example itself with your object and keys, until it works an then alter yours, exactly like the example... :)
Compound Query
PFQuery *query1 = [PFQuery queryWithClassName:#"Class1"];
[name whereKey:#"column1" equalTo:[fieldInCode text]];
PFQuery *query2 = [PFQuery queryWithClassName:#"Class1"];
[enterKey whereKey:#"column2" equalTo:[anotherField text]];
PFQuery *query = [PFQuery orQueryWithSubqueries:#[query1,query2]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
Cheers!

UISearchBartextfield -webview called.this method is no longer supported with the new text architecture

I am getting this error and my search function does nothing when the user starts typing a query( XCODE 5.1).
I dont know how the -webView is related to this error as I have not used webView in these files. Any advice would be appreciated. Thank you.
OrdersViewController.h
#import <UIKit/UIKit.h>
#interface OrdersViewController : UITableViewController <UISearchBarDelegate>
//NSmurray is set because we want to edit/move items as well (this will be implemented later)
#property (nonatomic, strong) NSMutableArray *jsonParseArray;
#property (nonatomic, strong) NSMutableArray *ordersArray;
#property (strong, nonatomic) IBOutlet UISearchBar *searchOrders;
#property (nonatomic, strong ) NSMutableArray *orderSearchResults;
#pragma mark -
#pragma mark Class Methods
-(void) retrieveOrderData;
#end
OrdersViewController.m
#import "OrdersViewController.h"
#import "Order.h"
#import "OrderDetailViewController.h"
#define getDataURL #"http://gkhns-macbook-pro.local/gj-3.php"
#interface OrdersViewController ()
#end
#implementation OrdersViewController
#synthesize jsonParseArray, ordersArray;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
//
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.title = #"ORDERS";
[self retrieveOrderData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)searchThroughOrders {
self.orderSearchResults = nil;
//gettig the text that is entered in the search bar and it creates nspredicated self containes the search and this text will be replaced by search field
NSPredicate *orderResultsPredicate = [NSPredicate predicateWithFormat:#"SELF contains [search] %#", self.searchOrders.text];
//filtering the predicate that is set before
self.orderSearchResults = [[self.ordersArray filteredArrayUsingPredicate:orderResultsPredicate] mutableCopy];
}
//detect when the user typed in the search
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self searchThroughOrders];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//are we in regular table view or search display view? Lets check that
if (tableView == self.tableView)
{
return ordersArray.count;
}
else{
[self searchThroughOrders];
// Return the number of rows in the section.
return self.orderSearchResults.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"OrderCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle=UITableViewCellStyleDefault;
}
if (tableView== self.tableView)
// Configure the cell...
{Order *orderObject;
orderObject = [ordersArray objectAtIndex:indexPath.row];
cell.textLabel.text=orderObject.order_id;
cell.detailTextLabel.text=orderObject.firstname;
}
else
{
cell.textLabel.text = self.orderSearchResults [indexPath.row];
}
//accessory
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Navigation
//In a story board-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if ([[segue identifier] isEqualToString:#"pushOrderDetailView"]){
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Order* object = [ordersArray objectAtIndex:indexPath.row];
[[segue destinationViewController] getOrder:object];
}
}
#pragma mark -
#pragma mark Class Methods
-(void) retrieveOrderData{
NSURL * url = [NSURL URLWithString:getDataURL];
NSData * data = [NSData dataWithContentsOfURL:url];
jsonParseArray=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
//orders array
ordersArray= [[NSMutableArray alloc]init];
//loop through the jason array
for (int i=0; i<jsonParseArray.count; i++)
{
//create the order object
NSString *oId = [[jsonParseArray objectAtIndex:i] objectForKey:#"order_id"];
NSString *eMail = [[jsonParseArray objectAtIndex:i] objectForKey:#"email"];
NSString *fName = [[jsonParseArray objectAtIndex:i] objectForKey:#"firstname"];
NSString *lName = [[jsonParseArray objectAtIndex:i] objectForKey:#"lastname"];
NSString *sName = [[jsonParseArray objectAtIndex:i] objectForKey:#"store_name"];
NSString *iPrefix = [[jsonParseArray objectAtIndex:i] objectForKey:#"invoice_prefix"];
NSString *pAddress1 = [[jsonParseArray objectAtIndex:i] objectForKey:#"payment_address_1"];
NSString *sPaymentAddress2 = [[jsonParseArray objectAtIndex:i] objectForKey:#"payment_address_2"];
//add order to orders array
[ordersArray addObject:[[Order alloc]initWithOrderId: (NSString *)oId andInvoicePrefix: (NSString*)iPrefix andStoreName:(NSString*)sName andFirstName:(NSString*)fName andLastName:(NSString*)lName andEmail:(NSString*)eMail andPaymentAddress1:(NSString*)pAddress1 andPaymentAddress2:(NSString*)sPaymentAddress2]];
}
//reload the view
[self.tableView reloadData];
}
#end
I was using searchbar only instead of search bar and the search display controller which may have caused this issue.
Also done a few changes to the searchdisplay controller implementation below which fixed the issue.
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self searchThroughOrders:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
-(void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView{
[tableView registerClass:[CustomOrdersCell class] forCellReuseIdentifier:#"OrderCell"];
}
-(void)searchThroughOrders:(NSString *)searchText scope:(NSString*)scope {
//getting the text that is entered in the search bar and it creates nspredicated self containes the search and this text will be replaced by search field
NSPredicate *orderResultsPredicate = [NSPredicate predicateWithFormat:#"order_id contains[c] %#", searchText];
//filtering the predicate that is set before
_orderSearchResults = [ordersArray filteredArrayUsingPredicate:orderResultsPredicate];
}

table view not showing

I'm working on this app, but somehow, its not returning any rows in my tableviewcontroller.
here is my code:
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define kStudentenURL [NSURL URLWithString:#"http://localhost/api/api.php"]
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface MasterViewController () {
NSArray *_studenten; } #end
#implementation MasterViewController
- (void)awakeFromNib {
[super awakeFromNib]; }
- (void)viewDidLoad {
[super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.
// The hud will dispable all input on the view (use the higest view possible in the view hierarchy) HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view]; [self.navigationController.view addSubview:HUD]; // Regiser for HUD callbacks so we can remove it from the window at the right time HUD.delegate = self; // Show the HUD while the provided method executes in a new thread [HUD showWhileExecuting:#selector(getJsonDataFromServer) onTarget:self withObject:nil animated:YES]; }
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated. }
-(void)getJsonDataFromServer {
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
kStudentenURL];
[self performSelectorOnMainThread:#selector(fetchedData:)
withObject:data waitUntilDone:YES];
}); }
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
_studenten = [json objectForKey:#"studenten"];
NSLog(#"Studenten: %#", _studenten);
NSLog(#"%u", _studenten.count); }
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _studenten.count; }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSDictionary *student = [_studenten objectAtIndex:0];
NSString *studentNaam = [student objectForKey:#"studentNaam"];
NSString *studentAchterNaam = [student objectForKey:#"studentAchterNaam"];
cell.textLabel.text = studentAchterNaam;
cell.detailTextLabel.text = studentNaam;
return cell; }
/* // Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { }
*/
/* // Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES; }
*/
/*- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDate *object = _objects[indexPath.row];
[[segue destinationViewController] setDetailItem:object];
} }*/
#end
I know my json is comming in correctly. the NSLogs are returning the data i ask, but i cant seem to get any rows. Can someone give me a hand? tnx
Simple answer -- you need to call [(your tableview) reloadData] once you've finished loading that data array!
Presumably you've got your tableview on the storyboard right now, and you've set it's datasource and delegate to your view controller. You will also need to have a property in your view controller to that tableview. You might have some code that looks like this.
#interface MasterViewController () {
NSArray *_studenten;
}
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#end
#implementation MasterViewController
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
_studenten = [json objectForKey:#"studenten"];
NSLog(#"Studenten: %#", _studenten);
NSLog(#"%u", _studenten.count);
[self.tableView reloadData];
}
#end
My guess is that you are never getting a valid cell returned from dequeueReusableCell. What I recommend doing is after you try to reuse a cell, check to see if it is nil, if so you need to alloc a new cell. I've added the code to your function.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if(!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
NSDictionary *student = [_studenten objectAtIndex:0];
NSString *studentNaam = [student objectForKey:#"studentNaam"];
NSString *studentAchterNaam = [student objectForKey:#"studentAchterNaam"];
cell.textLabel.text = studentAchterNaam;
cell.detailTextLabel.text = studentNaam;
return cell; }