how to parse diffrent array of dictionary in every uicollectionviewcell.? - ios

I have a api please look at this first.
{"result":"Successful","data":[{"price":"100.00","packs":"Garbage Bags","pack_id":"1","products":[{"quantity":"15","image":"1454651885ECOWGBS_03.jpg"},{"quantity":"15","image":"1454652017ECOWGBM_03.jpg"},{"quantity":"15","image":"1454652132ECOWGBL_02.jpg"}]},{"price":"200.00","packs":"Party","pack_id":"2","products":[{"quantity":"50","image":"1454589144USI_6819.jpg"},{"quantity":"50","image":"1454587252ecow240b_01.jpg"},{"quantity":"50","image":"1454499020ecow10rp_01.jpg"}]},{"price":"300.00","packs":"Travel","pack_id":"3","products":[{"quantity":"25","image":"1454589144USI_6819.jpg"},{"quantity":"25","image":"1454588615ecow103crp_01.jpg"},{"quantity":"25","image":"1455532004ECOWCLAM1_03.jpg"}]},{"price":"400.00","packs":"Kids","pack_id":"4","products":[{"quantity":"25","image":"1454499251ecow6rp_01.jpg"},{"quantity":"25","image":"1454588417ecow5ct_01.jpg"},{"quantity":"25","image":"1454587802ecow340b_01.jpg"}]}]}
Number of cell is generated demand upon the number of packs in api. For example in this api four pack are there so i parse the total number of pack and add it to array and than add that array in uicollectionview like this.
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [packdetail count];
}
Till now all thing working fine but when i tried to pass quantity in products data on uilabel it display on every cell and for only first products array. but i need to pass first products array on first cell and second product array on second cell and so on. Here is my code please look at this.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSArray *dataarray = [[NSJSONSerialization JSONObjectWithData:data options:0 error:nil]objectForKey:#"data"];
[packdetail removeAllObjects];
for (NSDictionary *tmp in dataarray)
{
NSMutableDictionary *temp = [NSMutableDictionary new];
[temp setObject:[tmp objectForKey:#"packs"] forKey:#"packs"];
[temp setObject:[tmp objectForKey:#"pack_id"] forKey:#"pack_id"];
[packdetail addObject:temp];
NSLog(#"packdetail %#", packdetail);
productarray = [tmp objectForKey:#"products"];
NSLog(#"products %#", productarray);
for (NSDictionary *product in productarray) {
NSMutableDictionary *temp2 =[NSMutableDictionary new];
[temp2 setObject:[product objectForKey:#"quantity"]forKey:#"quantity"];
[quantity addObject:temp2];
}
}
if (packdetail)
{
[_subscriptioncollectionview reloadData];
}
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [packdetail count];
}
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
SubscriptionCell *cell = (SubscriptionCell*)[collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.packname.text = [[packdetail objectAtIndex:indexPath.row] objectForKey:#"packs"];
cell.productname.text = [[quantity objectAtIndex:indexPath.row] objectForKey:#"quantity"];
return cell;
}

Your answer is
for (NSDictionary *tmp in dataarray)
{
NSMutableDictionary *temp = [NSMutableDictionary new];
[temp setObject:[tmp objectForKey:#"packs"] forKey:#"packs"];
[temp setObject:[tmp objectForKey:#"pack_id"] forKey:#"pack_id"];
[packdetail addObject:temp];
NSLog(#"packdetail %#", packdetail);
productarray = [tmp objectForKey:#"products"];
NSLog(#"products %#", productarray);
for (NSDictionary *product in productarray) {
NSMutableDictionary *temp2 =[NSMutableDictionary new];
[temp2 setObject:[product objectForKey:#"quantity"]forKey:#"quantity"];
[quantity addObject:temp2];
}
}
Change to
for (NSDictionary *tmp in dataarray)
{
NSMutableDictionary *temp = [NSMutableDictionary new];
[temp setObject:[tmp objectForKey:#"packs"] forKey:#"packs"];
[temp setObject:[tmp objectForKey:#"pack_id"] forKey:#"pack_id"];
NSLog(#"packdetail %#", packdetail);
productarray = [tmp objectForKey:#"products"];
NSLog(#"products %#", productarray);
for (NSDictionary *product in productarray) {
[temp setObject:[product objectForKey:#"quantity"]forKey:#"quantity"];
}
[packdetail addObject:temp];
}
Display in cell
cell.label.text = [[packdetail objectAtIndex:indexPath.row] objectForKey:#"quantity"];;

NSArray *array = [JsonArray];
in CellForRowAtIndexPath:
cell.label.text = [[[array objectAtIndex:indexPath.section] objectForKey:#"products"][indexpath.row]valueForkey #"quantity"];

Related

Program flow issues in ios

I am parsing a json to display the contents in the tableview. I have the array containing parsed json being populated in getReceivedData which is called after the UITAbleView Delegate methods. So it is problem in populating tableview as when the compiler attempts to populate it the array is not yet initialized.
- (void)getReceivedData:(NSMutableData *)data sender:(RestAPI *)sender{
NSError * error=nil;
NSArray *receivedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSString *dictionaryKey=#"department";
NSString *predicateString=#"software";
NSPredicate *predicate=[NSPredicate predicateWithFormat:#" %K == %# ", dictionaryKey,predicateString];
NSArray *shortlisted=[receivedData filteredArrayUsingPredicate:predicate];
for(int i = 0; i<shortlisted.count; i++)
{
NSDictionary *detailItems=[shortlisted objectAtIndex:i];
NSString *name=[detailItems objectForKey:#"emp_name"];
NSString *designation=[detailItems objectForKey:#"designation"];
NSString *email=[detailItems objectForKey:#"email"];
NSString *phone_no=[detailItems objectForKey:#"phone_no"];
// NSString *image=[detailItems objectForKey:#"url_path"];
dictionary1=[NSMutableDictionary dictionaryWithObjectsAndKeys:
name, #"keyname",
designation, #"keydesignation",
email, #"keyid",
phone_no, #"keyphone",
nil];
[myObject1 addObject:dictionary1];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section{
if(isfiltered==YES){
return [filteredArray count];
}
else{
return [myObject1 count];
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MyTableCell *cell=[tableView dequeueReusableCellWithIdentifier:#"myCell"];
if(!cell){
[tableView registerNib:[UINib nibWithNibName:#"MyTableCell" bundle:nil]
forCellReuseIdentifier:#"myCell"];
cell=[tableView dequeueReusableCellWithIdentifier:#"myCell"];
}
if(isfiltered==NO)
{
NSDictionary * tmpdict= [myObject objectAtIndex:indexPath.row];
cell.nameLabel.text=[NSMutableString stringWithFormat:#"%#",[tmpdict objectForKeyedSubscript:#"keyname"]];
cell.designationLabel.text=[NSMutableString stringWithFormat:#"%#",[tmpdict objectForKeyedSubscript:#"keydesignation"]];
cell.idLabel.text=[NSMutableString stringWithFormat:#"%#",[tmpdict objectForKeyedSubscript:#"keyid"]];
cell.phoneLabel.text=[NSMutableString stringWithFormat:#"%#",[tmpdict objectForKeyedSubscript:#"keyphone"]];
cell.mainImg.image = [UIImage imageNamed:[tmpdict objectForKeyedSubscript:#"keyimage"]];
}
else{
NSDictionary * tmpdict= [filteredArray objectAtIndex:indexPath.row];
cell.nameLabel.text=[NSMutableString stringWithFormat:#"%#",[tmpdict objectForKeyedSubscript:#"keyname"]];
cell.designationLabel.text=[NSMutableString stringWithFormat:#"%#",[tmpdict objectForKeyedSubscript:#"keydesignation"]];
cell.idLabel.text=[NSMutableString stringWithFormat:#"%#",[tmpdict objectForKeyedSubscript:#"keyid"]];
cell.phoneLabel.text=[NSMutableString stringWithFormat:#"%#",[tmpdict objectForKeyedSubscript:#"keyphone"]];
cell.mainImg.image = [UIImage imageNamed:[tmpdict objectForKeyedSubscript:#"keyimage"]];
}
return cell;
}
This window was supposed to view the table
In a mutable dictionary first you have to give object then its key. You are doing wrong
for(int i = 0; i<shortlisted.count; i++)
{
NSDictionary *detailItems=[shortlisted objectAtIndex:i];
NSString *name=[detailItems objectForKey:#"emp_name"];
NSString *designation=[detailItems objectForKey:#"designation"];
NSString *email=[detailItems objectForKey:#"email"];
NSString *phone_no=[detailItems objectForKey:#"phone_no"];
dictionary1=[NSMutableDictionary dictionaryWithObjectsAndKeys:
name,#"keyname",
designation,#"keydesignation",
email,#"keyid",
phone_no,#"keyphone",
nil];
[myObject1 addObject:dictionary1];
}
Actually this is not correct way to intialize dictionary as you did, #"%#" is used %# is a placeholder in a format string for any object.
dictionary1=[NSMutableDictionary dictionaryWithObjectsAndKeys:
name,#"keyname",
designation,#"keydesignation",
email,#"keyid",
phone_no,#"keyphone",
nil];

How to create uilabel dynamically according to array coming from API.?

i need to create uilabel dynamically according to length of array coming from web service. please look at my web service structure.
{"result":"Successful","data":[{"price":"100.00","packs":"Bio Bags","pack_id":"1","products":[{"quantity":"15","image":"1454651885ECOWGBS_03.jpg"},{"quantity":"15","image":"1454652017ECOWGBM_03.jpg"},{"quantity":"15","image":"1454652132ECOWGBL_02.jpg"}]},{"price":"200.00","packs":"Party Pack","pack_id":"2","products":[{"quantity":"50","image":"1454589144USI_6819.jpg"},{"quantity":"50","image":"1454587252ecow240b_01.jpg"},{"quantity":"50","image":"1454499020ecow10rp_01.jpg"}]},{"price":"300.00","packs":"Travel Pack","pack_id":"3","products":[{"quantity":"25","image":"1454589144USI_6819.jpg"},{"quantity":"25","image":"1454588615ecow103crp_01.jpg"},{"quantity":"25","image":"1454588259ecowclam_01.jpg"}]},{"price":"400.00","packs":"Kids Pack","pack_id":"4","products":[{"quantity":"25","image":"1454499251ecow6rp_01.jpg"},{"quantity":"25","image":"1454588417ecow5ct_01.jpg"},{"quantity":"25","image":"1454587802ecow340b_01.jpg"}]}]}
i need to set quantity name and image on uilabel and uiimage as well in uicollectionview cell.sometime quantity name can be 3 sometime it can be 20. Write now i am add it to stoically. please look at my code below.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSArray *dataarray = [[NSJSONSerialization JSONObjectWithData:data options:0 error:nil]objectForKey:#"data"];
[packdetail removeAllObjects];
for (NSDictionary *tmp in dataarray)
{
NSMutableDictionary *temp = [NSMutableDictionary new];
[temp setObject:[tmp objectForKey:#"packs"] forKey:#"packs"];
[temp setObject:[tmp objectForKey:#"pack_id"] forKey:#"pack_id"];
[packdetail addObject:temp];
NSArray *productarray = [tmp objectForKey:#"products"];
NSLog(#"products %#", productarray);
for (NSDictionary *product in productarray) {
NSMutableDictionary *temp2 =[NSMutableDictionary new];
[temp2 setObject:[product objectForKey:#"quantity"]forKey:#"quantity"];
NSLog(#"temp2 %#", temp2);
[quantity addObject:temp2];
}
}
if (packdetail)
{
[_subscriptioncollectionview reloadData];
}
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [packdetail count];
}
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
SubscriptionCell *cell = (SubscriptionCell*)[collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.packname.text = [[packdetail objectAtIndex:indexPath.row] objectForKey:#"packs"];
cell.productname.text = [[quantity objectAtIndex:indexPath.row] objectForKey:#"quantity"];
return cell;
}
Just give me some basic idea so i can move forward.

Get JSON Data from Array Within an Array

I am trying to figure out how I can get data from a JSON array that is in another array.
Here is the JSON. I'm wanting to get one of the image URLs from photos.
[
{
"id":6901439,
"name":"INDTTIN CD",
"description":"Full-length released June 2013 via Little Heart Records. \r\n\r\nTrack Listing:\r\n\r\n1. Tired\r\n2. Time to Heal\r\n3. Gypsy Summer\r\n4. Sketchbooks\r\n5. I Never Deserve the Things I Need\r\n6. Say it With the \"I\"\r\n7. A Negative Mind\r\n8. Rafters\r\n9. Indrid Cold\r\n10. Present Tense ",
"short_url":"http://onmyhonor.storenvy.com/products/6901439-indttin-cd",
"status":"active",
"labels":null,
"preorder":false,
"on_sale":true,
"store_id":373949,
"price":"7.00",
"marketplace_category":"music-cds",
"marketplace_category_id":345,
"photos":[
{
"photo":{
"original":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_original.jpg",
"large":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_large.jpg",
"homepage":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_homepage.jpg",
"medium":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_medium.jpg",
"small":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_small.jpg",
"64w":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_64w.jpg",
"200w":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_200w.jpg",
"400w":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_400w.jpg",
"600w":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_600w.jpg",
"1000w":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_1000w.jpg",
"64sq":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_64sq.jpg",
"200sq":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_200sq.jpg",
"400sq":"//d111vui60acwyt.cloudfront.net/product_photos/15878486/inddthin_20vinyl_20image_201_400sq.jpg"
}
}
],
"variants":[
{
"variant":{
"id":14382188,
"name":"INDTTIN CD",
"position":1,
"sku":"",
"full_quantity":300,
"in_stock":300,
"percent_available":100,
"is_default_variant?":false,
"price":7.0,
"sold_out":false,
"status":"active"
}
}
],
"collections":[
],
"store":{
"id":373949,
"name":"On My Honor",
"marketplace_url":"http://www.storenvy.com/stores/373949-on-my-honor"
}
}
]
Here is my code:
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define storeURL [NSURL URLWithString: #"http://onmyhonor.storenvy.com/products.json"]
#import "GRSStoreViewController.h"
#import "GRSStoreDetailViewController.h"
#interface GRSStoreViewController ()
#end
#implementation GRSStoreViewController
#synthesize name, description, short_url, price, productImage, nameArray, descriptionArray, urlArray, priceArray, imageArray, url;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Store";
self.tableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped];
url = [NSURL URLWithString:#"http://onmyhonor.storenvy.com/products.json"];
dispatch_async(kBgQueue, ^{
NSData *data = [NSData dataWithContentsOfURL:url];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData
{
NSError *error;
nameArray = [[NSMutableArray alloc]init];
descriptionArray = [[NSMutableArray alloc]init];
urlArray = [[NSMutableArray alloc]init];
priceArray = [[NSMutableArray alloc]init];
imageArray = [[NSMutableArray alloc]init];
NSArray *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
for (NSDictionary *item in json)
{
name = [item objectForKey:#"name"];
description = [item objectForKey:#"description"];
short_url = [item objectForKey:#"short_url"];
price = [item objectForKey:#"price"];
[nameArray addObject:name];
[descriptionArray addObject:description];
[urlArray addObject:short_url];
[priceArray addObject:price];
}
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [nameArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
cell.textLabel.font = [UIFont systemFontOfSize:16.0];
}
if (cell)
{
cell.textLabel.text = [nameArray objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor darkGrayColor];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
GRSStoreDetailViewController *itemDetail = [[GRSStoreDetailViewController alloc]initWithNibName:#"GRSStoreDetailViewController" bundle:nil];
itemDetail.priceString = [priceArray objectAtIndex:indexPath.row];
itemDetail.descriptionString = [descriptionArray objectAtIndex:indexPath.row];
itemDetail.itemURL = [urlArray objectAtIndex:indexPath.row];
[self.navigationController pushViewController:itemDetail animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Change loop to
for (NSDictionary *item in json)
{
NSArray *photos = item[#"photos"];
NSDictionary *dict = [photos[0] valueForKeyPath:"photo"];
NSLog(#"original = %#", dict[#"original"]);
name = [item objectForKey:#"name"];
description = [item objectForKey:#"description"];
short_url = [item objectForKey:#"short_url"];
price = [item objectForKey:#"price"];
[nameArray addObject:name];
[descriptionArray addObject:description];
[urlArray addObject:short_url];
[priceArray addObject:price];
}
Change this
NSArray *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
for (NSDictionary *item in json)
{
name = [item objectForKey:#"name"];
description = [item objectForKey:#"description"];
short_url = [item objectForKey:#"short_url"];
price = [item objectForKey:#"price"];
[nameArray addObject:name];
[descriptionArray addObject:description];
[urlArray addObject:short_url];
[priceArray addObject:price];
}
[self.tableView reloadData];
To this
NSdictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
name = [json objectForKey:#"name"];
description = [json objectForKey:#"description"];
short_url = [json objectForKey:#"short_url"];
price = [json objectForKey:#"price"];
// this is your photos array
NSArray *photos = [josn objectForKey:#"photos"];
// every object in this array is a dictionary. In your case this array has only one dictionary so
NSDictionary *photosDict = [photos firstObject];
// from here you can access all keys of photosDict
All available keys in your photosDict:
original
large
homepage
medium
small
64w
200w
400w
600w
1000w
64sq
200sq
400sq

Can't implement search filter to my table data using NSPredicate

Now my search work by sectionsTitle, if I write "Category1" or "Category2" it find section Category1, or Category2, but I need to search by NAMES in all this sections, from here:
NSDictionary *dict = [[tableData objectForKey:[sectionsTitle objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
[NSString stringWithFormat:#"%#", [dict objectForKey:#"Name"]];
What I need to change in my code for search by Names? Now I'm confused with all that NSArray's, NSMutableArray's and NSDictionary :(
I load my data like this:
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [[documentPaths lastObject] stringByAppendingPathComponent:#"data.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSMutableDictionary *resultDic = [[NSMutableDictionary alloc] init];
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
sectionKeys = [NSMutableArray new];
sectionsTitle = [NSMutableArray new];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"blueKey"])
{
ann = [dict objectForKey:#"Category1"];
[resultArray addObject:#"Category1"];
[resultDic setValue:ann forKey:#"Category1"];
[sectionKeys addObject:#"Section 1"];
}
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"yellowKey"])
{
ann = [dict objectForKey:#"Category2"];
[resultArray addObject:#"Category2"];
[resultDic setValue:ann forKey:#"Category2"];
[sectionKeys addObject:#"Section 2"];
}
self.tableData = resultDic;
self.sectionsTitle = resultArray;
[myTable reloadData];
This is how I filter data:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
searchResults = [sectionsTitle filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
This is how my table look like:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView == self.searchDisplayController.searchResultsTableView) {
return 1;
}else{
return sectionKeys.count;
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (tableView == self.searchDisplayController.searchResultsTableView) {
return #"Search";
}else{
return [sectionKeys objectAtIndex:section];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
int num = [[tableData objectForKey:[sectionsTitle objectAtIndex:section]] count];
return num;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
} else {
NSDictionary *dict = [[tableData objectForKey:[sectionsTitle objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont fontWithName:#"Avenir" size: 16.0];
cell.detailTextLabel.font = [UIFont fontWithName:#"Avenir" size: 12.0];
cell.textLabel.text = [NSString stringWithFormat:#"%#", [dict objectForKey:#"Name"]];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", [dict objectForKey:#"Address"]];
}
return cell;
}
My data structure:
With a simplified data set (only the Name entry included in the dictionaries), this should reproduce your setup:
NSArray *categories = #[
#[#{#"Name":#"Joe"}, #{#"Name":#"Jane"}],
#[#{#"Name":#"Anne"}, #{#"Name":#"Bob"}]
];
Then the ANY operator of NSPredicate will find the array you are after:
NSString *nameToSearch = #"Bob";
NSPredicate *catPred = [NSPredicate predicateWithFormat:#"ANY Name = %#", nameToSearch];
To see how this predicate can filter your category array:
NSArray *filteredCats = [categories filteredArrayUsingPredicate:catPred];
BTW, you might get less confused if you build some custom objects to hold your data instead of relying only on arrays and dictionaries.

Filter NSMutableDictionary data in UITableView

I need to filter data in UITableview by text entered in UISearchbar. I followed this example but there data in NSMutableArray and I can't alter it under my requirements. My data is NSMutableDictionary. I'm stuck on this for long time.
My data:
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [[documentPaths lastObject] stringByAppendingPathComponent:#"data.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSMutableDictionary *resultDic = [[NSMutableDictionary alloc] init];
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
NSDictionary *myDict = [NSDictionary dictionaryWithContentsOfFile:path];
sectionKeys = [NSMutableArray new];
sectionsTitle = [NSMutableArray new];
NSArray *tableArray = [myDict objectForKey:#"Black"];
[resultArray addObject:#"Black"];
[resultDic setValue:tableArray forKey:#"Black"];
[sectionsTitle addObject:[NSString stringWithFormat:#"%#", [tableData valueForKey:#"Black"]]];
[sectionCord addObject:[NSString stringWithFormat:#"%#", [tableData valueForKey:#"Coordinates"]]];
[sectionKeys addObject:#"Section1"];
self.tableData = resultDic;
self.sectionsTitle = resultArray;
[myTable reloadData];
My table:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return sectionKeys.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [sectionKeys objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
int rowCount;
if(self.isFiltered)
rowCount = [[filteredTableData objectForKey:[sectionsTitle objectAtIndex:section]] count];
else
rowCount = [[tableData objectForKey:[sectionsTitle objectAtIndex:section]] count];
return rowCount;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
if(isFiltered){
NSDictionary *dict = [[filteredTableData objectForKey:[sectionsTitle objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%#", [dict objectForKey:#"Name"]];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", [dict objectForKey:#"Address"]];
}
else{
NSDictionary *dict = [[tableData objectForKey:[sectionsTitle objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%#", [dict objectForKey:#"Name"]];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", [dict objectForKey:#"Address"]];
}
return cell;
}
My search:
#pragma mark - SearchBar Delegate -
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)text{
if(text.length == 0)
{
isFiltered = FALSE;
NSLog(#"false");
}
else
{
isFiltered = true;
NSLog(#"true");
filteredTableData = [[NSMutableDictionary alloc] init];
for (MyAnnotation* ann in tableData)
{
NSRange nameRange = [ann.title rangeOfString:text options:NSCaseInsensitiveSearch];
NSRange descriptionRange = [ann.description rangeOfString:text options:NSCaseInsensitiveSearch];
if(nameRange.location != NSNotFound || descriptionRange.location != NSNotFound)
{
[filteredTableData addObject:ann];
//error
}
}
}
[myTable reloadData];
}
First of all, you need to create a state/flag for the controller/data source, in order for it to know weather you are in search/filter mode.
Then, if you are in search mode, point the data source methods to the filteredArray.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
int numberOfSections = 0;
if (_searchMode)
{
numberOfSections = self.filteredDataDict.allKeys.count;
}
else
{
numberOfSections = self.tableData.allKeys.count;
}
return numberOfSections;
}
Hope it's understood.

Resources