I want to avoid tableview/collectionview cells with duplicate values.
Here is my code :
NSURL *imageURL = [NSURL URLWithString:[finalImage objectAtIndex:indexPath.row]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (nonatomic, strong) NSArray *imagesArray; //Array of URL for images
#property (nonatomic, strong) NSMutableDictionary *dataDictionary; // Using to store downloaded data
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//Some images for test
self.imagesArray = #[#"https://cdn.pixabay.com/photo/2017/05/31/18/38/sea-2361247__480.jpg", #"https://cdn.pixabay.com/photo/2017/06/02/11/49/still-life-2366084__480.jpg", #"https://cdn.pixabay.com/photo/2017/06/04/20/31/sheep-2372148__480.jpg", #"https://cdn.pixabay.com/photo/2017/06/04/15/08/architecture-2371294__480.jpg", #"https://cdn.pixabay.com/photo/2017/05/18/21/54/tower-bridge-2324875__480.jpg", #"https://cdn.pixabay.com/photo/2017/05/16/21/24/gorilla-2318998__480.jpg", #"https://cdn.pixabay.com/photo/2017/05/24/11/40/desert-2340326__480.jpg", #"https://cdn.pixabay.com/photo/2017/05/21/15/14/balloon-2331488__480.jpg", #"https://cdn.pixabay.com/photo/2017/05/19/15/16/countryside-2326787__480.jpg", #"https://cdn.pixabay.com/photo/2017/04/09/09/56/avenue-2215317__480.jpg"];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cell"];
self.dataDictionary = [NSMutableDictionary new];
}
- (void)asyncImageForIndexPath: (NSIndexPath *)indexPath onCompletion: (void(^)(UIImage *image))completionBlock {
NSURL *imageURL = [NSURL URLWithString:[self.imagesArray objectAtIndex:indexPath.row]];
if ([self.dataDictionary objectForKey:[NSString stringWithFormat:#"%ld", (long)indexPath.row]]) {
completionBlock([UIImage imageWithData:[self.dataDictionary objectForKey:[NSString stringWithFormat:#"%ld", (long)indexPath.row]]]);
}
//Sending async request not to block main thread and storing it into the dictionary
//After storing, reloading table view on main thread. So the function is called again, but as we have stored NSData for image, method won't send request
[[[NSURLSession sharedSession] dataTaskWithURL:imageURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if(!error) {
[self.dataDictionary setObject:data forKey:[NSString stringWithFormat:#"%ld", indexPath.row]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
}] resume];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 250;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.imagesArray.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
//Downloading image separated into another method
[self asyncImageForIndexPath:indexPath onCompletion:^(UIImage *image) {
cell.imageView.image = image;
}];
return cell;
}
Try out the code, and let me know if that helps. If you have any questions, feel free to ask
Related
I am using SDWebImage to show image in UICollectionView. I am getting productImageUrl and productId as server response. Able to show the image in Custom-cell, now what I want is:
1) Display the image in large view with a UIButton(buyButton) on another UIViewController named ProductDetailViewController.(Image is showing on the ProductDetailViewController but the way i am passing image url from ProductCollectionViewController is not right I think, please review the code and suggest me some better way to do it )
2) On button click a call will be made to the server with the productId which I got earlier as Server Response.(How would I pass the dictId to ProductDetailViewController so that I can make a call to the server).
3) Getting only two key-value of an Object as response, so its ok to parse it in multiple dictionary for multiple value. But If the response contain multiple value, what will be the optimized way to parse the response.
Here is the code which i have tried.
(Sorry for long unoptimized code, still in learning phase)
ProductCollectionViewController.m
#import "ProductCollectionViewController.h"
#import "ProductCell.h"
#import "UIImageView+WebCache.h"
#import "ProductDetailViewController.h"
#interface ProductCollectionViewController ()
#property(strong, nonatomic) NSMutableArray *productList;
#end
#implementation ProductCollectionViewController
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
static NSString * const reuseIdentifier = #"Cell";
-(void)viewDidLoad
{
[super viewDidLoad];
[self getProductList];
}
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void)getProductList
{
NSURL * url = [NSURL URLWithString:#"xxxx.yyyy.zzzz"];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject];
NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
if (!error)
{
NSDictionary *responseJson = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSArray *rsBody = responseJson[#"rsBody"];
_productList = [NSMutableArray new];
for(NSDictionary *dict in rsBody)
{
NSMutableDictionary *dictUrl=[[NSMutableDictionary alloc]init];
NSMutableDictionary *dictProductId =[[NSMutableDictionary alloc]init];
[dictUrl setValue:[dict valueForKey:#"productImageUrl"] forKey:#"url"];
[dictId setValue:[dict valueForKey:#"productId"] forKey:#"id"];
[_productList addObject:dictUrl];
[_productList addObject:dictId];
}
NSLog(#"urls for image: %#",_productList );
[self.collectionView reloadData];
}}];
[dataTask resume];
}
#pragma mark <UICollectionViewDataSource>
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return _productList.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
ProductCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
NSURL *imageUrl = [[_productList objectAtIndex:indexPath.row]valueForKey:#"url"];
[cell.productImageView sd_setImageWithURL:imageUrl placeholderImage:[UIImage imageNamed:#"placeholder.jpg"]];
NSString *id =[[_productList objectAtIndex:indexPath.row] valueForKey:#"id"];
cell.productPrice.text= id;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showProduct"]) {
NSArray *indexPaths = [self.collectionView indexPathsForSelectedItems];
ProductDetailViewController *destViewController = segue.destinationViewController;
NSIndexPath *indexPath = [indexPaths objectAtIndex:0]
destViewController.productName =[[_productList objectAtIndex:indexPath.row]valueForKey:#"url"];
[self.collectionView deselectItemAtIndexPath:indexPath animated:NO];
}
}
#end
ProductDetailViewController.h
`#import <UIKit/UIKit.h>
#interface ProductDetailViewController : UIViewController
- (IBAction)buyButton:(id)sender;
- (IBAction)closeButton:(id)sender;
#property (weak, nonatomic) IBOutlet UIImageView *productImage;
#property (weak, nonatomic) NSString *productName;
#end`
ProductDetailViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.productImage.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.productName]]];
//code to get productId
}
- (IBAction)buyButton:(id)sender {
//code to make server call with productId.
}
Server Response Format in JSON
{"rsBody":
[{"productId":11,
"productImageUrl":"http:xxxx"},
{"productId":9,
"productImageUrl":"http:"xxxx"}]}
For your first question, this line
self.productImage.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.productName]]];
is blocking the main thread. Meaning the app will go to the server download the entire image before updating the screen or allowing interactions, which is bad.
NSURL *url = [[NSURL alloc]initWithString:self.productName];
dispatch_queue_t imageFetchQ = dispatch_queue_create("image fetcher", NULL);
dispatch_async(imageFetchQ, ^{
NSData *imageData = [[NSData alloc] initWithContentsOfURL:url];
UIImage *image = [[UIImage alloc]initWithData:imageData];
dispatch_async(dispatch_get_main_queue(), ^{
self.productImage.image=image;
}
});
});
Try the block above instead. It will fetch the product image on a different thread.
Question two: Two transfer data between view controllers do what you're doing in prepareForSegue setup the public properties of the destination view controller.
Question three: Optimum way is to create an NSObject class that you read the data from the dictionary into properties on that class through some method called like setupFromDictionary.
Here you would have an Object called product with a productID property and productImageURL property. That way you're not constantly calling valueForKey or objectForKey on some dictionary.
I created an api using kimono and here is my code.
#import "PlayerRankingsTableViewController.h"
#import "RankingsTableViewCell.h"
#define kBgQueue dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define kPlayerRankingsURL [NSURL URLWithString:#"https://www.kimonolabs.com/api/bg6tcuuq?apikey=xgp4nU6xA9UcBWSe0MIHcBVbAWz5v4wR"]
#interface PlayerRankingsTableViewController () {
}
#property (nonatomic, strong) NSArray *playerRankings;
#end
#implementation PlayerRankingsTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData *data = [NSData dataWithContentsOfURL:
kPlayerRankingsURL];
[self performSelectorOnMainThread: #selector(initializePlayerRankingsArray:)
withObject:data waitUntilDone:YES];
});
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be rexrcreated.
}
- (NSArray *)initializePlayerRankingsArray:(NSData *)responseData {
NSError* error;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSArray *myPlayerRankings = [[json objectForKey:#"results"]objectForKey:#"collection1"];
self.playerRankings = myPlayerRankings;
NSLog(#"%#", self.playerRankings);
return self.playerRankings;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.playerRankings count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
RankingsTableViewCell *cell = (RankingsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) {
cell = (RankingsTableViewCell *)[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
NSDictionary *rankings = [self.playerRankings objectAtIndex: indexPath.row];
NSString *rank = [rankings objectForKey:#"rank"];
NSString *name = [rankings objectForKey:#"name"];
NSString *points = [rankings objectForKey:#"points"];
[cell.playerRank setText:rank];
cell.playerName.text = name;
cell.playerPoints.text = points;
return cell;
}
#end
I think there is nothing wrong with data parsing process, because the console displays my data parsed from the web correctly.
However, when I ran the app, I saw nothing but a empty table.
Again, I think this might be something simple and new to programming.
Thank you in advance, and sorry for being such a burden.
In initializePlayerRankingsArray: you shouldn't be returning the array because nothing it there to receive it. You have already set self.playerRankings, so that is enough.
What is missing from this method is [self.tableView reloadData]; (which should be the last line after self.playerRankings is set).
I am currently trying to load a plist file from a URL. I'm not sure if the way I have my code set up is causing it to crash or if I'm doing something wrong.
.m file
#import "deptTableViewController.h"
#interface deptTableViewController ()
#property (nonatomic, copy) NSDictionary *names;
#property (nonatomic, copy) NSArray *keys;
#property (nonatomic, strong) NSMutableArray *filterednames;
#property (nonatomic, strong) UISearchDisplayController *searchController;
#end
#implementation deptTableViewController
#synthesize names, keys, filterednames, searchController, searchNames;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
UITableView *tableview = (id) [self.view viewWithTag:1];
[tableview registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
filterednames = [[NSMutableArray alloc]init];
searchController = [[UISearchDisplayController alloc]init];
searchController.searchResultsDataSource = self;
// This will get the plist into data format
NSData *dataReturn = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://morphinggamers.ca/staff.plist"]];
NSString *path = [[NSBundle mainBundle]pathForResource:#"staff" ofType:#"plist"];
names = [NSDictionary dictionaryWithContentsOfFile:path];
keys = [[names allKeys]sortedArrayUsingSelector:#selector(compare:)];
keys = [NSKeyedUnarchiver unarchiveObjectWithData:dataReturn];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (tableView.tag == 1) {
return [keys count];
}
else{
return 1;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (tableView.tag == 1) {
NSString *key = keys[section];
NSArray *keyValues = names[key];
return [keyValues count];
}
else {
return [filterednames count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
if (tableView.tag == 1) {
names = keys[indexPath.row];
NSString *teacherNames = names[#"teacherNames"];
cell.textLabel.text = teacherNames;
}
else{
cell.textLabel.text = filterednames [indexPath.row];
}
return cell;
}
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if (tableView.tag == 1) {
return keys[section];
}
else{
return nil;
}
}
#pragma mark - Search Display And Delegate Methods
-(void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView {
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{
[filterednames removeAllObjects];
if (searchString.length > 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains [search] %#", self.searchNames.text];
for (NSString *key in keys) {
NSArray *matches = [names[key]filteredArrayUsingPredicate:predicate];
[filterednames addObjectsFromArray:matches];
}
}
return YES;
}
#end
You can only use initwithcontentsofurl using local files (files on your device already) This URL is on a server so you need to use a network request to fetch the data from the server.
NSURLRequest *request = [NSURLRequest requestWithURL:#"http://morphinggamers.ca/staff.plist"];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSDictionary *names = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:0 format:0 errorDescription:nil];
keys = [[names allKeys]sortedArrayUsingSelector:#selector(compare:)];
keys = [NSKeyedUnarchiver unarchiveObjectWithData:dataReturn];
//might want to reload the tableview
[self.tableview reloadData]
}];
In my App, I have a list of news to be shown and I'm using custom tableview which has a Title, Thumbnail image and more button. On Tapping more button, it will take to the detail view which has description. I've parsed the JSON response for listing the feed in page. But I'm strucked with the detail page. Following is my code:
.m file
#interface NewsViewController ()
#property (nonatomic , retain) NSMutableArray *mArray;
#property (nonatomic , retain) NSDictionary *nDic;
#end
#implementation NewsViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://almithaq.mawaqaademo11.com/API.svc/getNews" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.nDic = (NSDictionary *)responseObject;
self.mArray = self.nDic[#"News"];
[self.mTab reloadData];
NSLog(#"response dateJSON: %#", self.mArray);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
#pragma mark - TableConfiguration
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.mArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Identifier = #"MyIdentifier";
NewsCell *cell12 = (NewsCell *)[tableView dequeueReusableCellWithIdentifier:Identifier];
if (cell12 == nil) {
NSArray *nib = [[NSBundle mainBundle]loadNibNamed:#"NewsCell" owner:self options:nil];
cell12 = [nib objectAtIndex:0];
}
cell12.newsDescription.text = [[self.mArray objectAtIndex:indexPath.row] objectForKey:#"Description"];
cell12.newsTitle.text = [[self.mArray objectAtIndex:indexPath.row] objectForKey:#"Title"];
cell12.newsThumbnail.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://%#",[[self.mArray objectAtIndex:indexPath.row] objectForKey:#"NewsImage"]]]]];
cell12.newsMore.tag = indexPath.row;
[cell12.newsMore addTarget:self action:#selector(NewsClicked:) forControlEvents:UIControlEventTouchUpInside];
return cell12;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 220;
}
-(void)backButtonClicked:(UIButton*)sender
{
if (sender.tag <= 25)
{
[self.navigationController popViewControllerAnimated:YES];
}
}
-(void)NewsClicked:(UIButton *)sender
{
if (sender.tag <= 25) {
NewsDetails *view1 = [[NewsDetails alloc]initWithNibName:#"NewsDetails" bundle:nil];
[self.navigationController pushViewController:view1 animated:YES];
}}
Advice, thanks in advance.
I am very new at Objective C and Xcode but I am learning a little bit every day!:)
I am trying to build an application that will show a webb api in my tableview, but it does not show.. when I NSLog it, it shows that my search worked and that it got the data i was looking for but it will not show in my tableView unfortunately..
If someone as time to look at the code and try to figure out what is wrong that would be great, or if someone hade a similar problem, just throw it out there so i can check if i did the same thing:)
Best regards. Filip
(Sorry for my bad english, I`m from Sweden and in a hurry..)
- my .m file
#import "FoodTableViewController.h"
#interface FoodTableViewController ()
#property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
#property(nonatomic)NSMutableArray *foodNames;
#end
#implementation FoodTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.foodNames = [#[]mutableCopy];
self.searchBar.delegate = 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)searchBarSearchButtonClicked:(UISearchBar *)searchbar
{
NSString *urlString = [NSString stringWithFormat:#"http://matapi.se/foodstuff?query=%#",self.searchBar.text];
NSURL *URL = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSError *parseError;
NSArray *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError];
dispatch_async(dispatch_get_main_queue(),^{
for(int i=0;i<json.count;i++){
NSString *foodName = json[i][#"name"];
[self.foodNames addObject:foodName];
NSLog(#"Added: %#",foodName);
NSLog(#"FOODLIST LENGTH: %d",self.foodNames.count);
}
});
}];
[task resume];
[self.tableView reloadData];
}
#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 self.foodNames.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if(self.foodNames[indexPath.row]){
NSLog(#"Cell text %#",self.foodNames[indexPath.row]);
cell.textLabel.text = self.foodNames[indexPath.row];
}else{
cell.textLabel.text = #"Loading..";
}
return cell;
}
#end
- my .h file
#import <UIKit/UIKit.h>
#interface FoodTableViewController : UITableViewController<UISearchBarDelegate>
#end
dataTaskWithRequest:... is an asynchronous method, which means that the results are not available at the time of your reloadData call. You'll need to add that call after all your data is added to the array. In part...
for(int i=0;i<json.count;i++){
NSString *foodName = json[i][#"name"];
[self.foodNames addObject:foodName];
NSLog(#"Added: %#",foodName);
NSLog(#"FOODLIST LENGTH: %d",self.foodNames.count);
}
[self.tableView reloadData];