Complex JSON as NSArray Datasource for a UITableView iOS - iphone

I tried almost everything before posting (google, Apple Dev Doc etc.). I hope I did not miss anything before posting..
I already built a working JSON <-> Webservice <-> iPhone login.
with the following code:
NSString *responseString = [[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]autorelease];
NSDictionary *jsonDict = [responseString JSONValue];
NSString *loginResult = [jsonDict valueForKey:#"LoginResult"];
loginResult is the name of the employee: e.g "Henning Wenger"
The corresponding JSON looks like this:
{"LoginResult":"S:00000412"}
Now I have a more complex task which I can´t manage to figure a way through:
I´m getting the following JSON from the webservice:
{"GetTeamPresentStatusResult"[
{"Firstname":"Steffen","Id":"00000456","IsPresent":"true","Lastname":"Polker"},
{"Firstname":"Erich","Id":"00000455","IsPresent":"true","Lastname":"Welter"},
{"Firstname":"Titus","Id":"00000454","IsPresent":"true","Lastname":"Sommerbeck"}, {"Firstname":"Ruediger","Id":"00000453","IsPresent":"true","Lastname":"Oelmann"},{"Firstname":"Heinz","Id":"00000452","IsPresent":"true","Lastname":"Radelfs"},{"Firstname":"Franz","Id":"00000451","IsPresent":"true","Lastname":"Wippermann"},{"Firstname":"Klaus-Dieter","Id":"00000450","IsPresent":"true","Lastname":"Just"},{"Firstname":"Alan","Id":"00000412","IsPresent":"true","Lastname":"Turing"},{"Firstname":"Konrad","Id":"00000138","IsPresent":"true","Lastname":"Zuse"},{"Firstname":"Marius","Id":"00000112","IsPresent":"true","Lastname":"Sandmann"}]}
My code for handling this starts with:
NSDictionary *jsonDict = [responseString JSONValue];
NSArray *teamStatus = [jsonDict objectForKey:#"GetTeamPresentStatusResult"];
[self BuildDataSource: nil :teamStatus];
teamStatus now contains 10 key/value pairs.
Here is how I tried to build up the datasource for my table:
- (void)BuildDataSource: (id) sender: (NSArray*)teamStatusData{
teamStatusMutableArray = [[NSMutableArray alloc]init];
teamStatusDataSection = [[NSArray alloc]initWithArray:teamStatusData];
teamStatusDictSectionOne = [NSDictionary dictionaryWithObject:teamStatusDataSection forKey:#"OrgUnits"];
[teamStatusMutableArray addObject:teamStatusDictSectionOne];
[tblView reloadData];
}
I can not manage to figure out which way to go from here to get the data how I need it.
Do I need different Arrays where one contains the firstname/value and another one that contains lastname/value? If yes, how do I do that?
Here are some lines I´ve tried so far which did not have helped:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
//First get the dictionary object
NSDictionary *dictionary = [teamStatusMutableArray objectAtIndex:indexPath.section];
NSString *testString = [dictionary valueForKey:#"Firstname"];
NSArray *testarray = [dictionary objectForKey:#"OrgUnits"];
NSString *test = [testarray JSONRepresentation];
test = [test stringByReplacingOccurrencesOfString:#"[" withString:#""];
test = [test stringByReplacingOccurrencesOfString:#"]" withString:#""];
NSDictionary *jsonDict = [test JSONValue];
}
What I need is to have a Datasource with the Employee Names that I can bind to a Table. From there I think I can make my way without additional help.
I´m coming from the .NET (C#) world and maybe this confuses me too much.
Thank you so much..
Henning
If you need further details please ask!
Details for SPtail:
Here is the .h file:
#import <UIKit/UIKit.h>
#import "RootViewController.h"
#import "EmployeeDetails.h"
#interface OrgUnitAA:NSObject {
NSString *FirstName;
NSString *Id;
NSString *IsPresent;
NSString *LastName;
}
#property (nonatomic, retain) NSString *FirstName;
#property (nonatomic, retain) NSString *Id;
#property (nonatomic, retain) NSString *IsPresent;
#property (nonatomic, retain) NSString *LastName;
#end
#interface TeamStatusView : UIViewController {
UITableView *tblView;
NSMutableArray *teamStatusMutableArray;
NSArray *teamStatusDataSection;
NSDictionary *teamStatusDictSectionOne;
UIViewController *EmployeeDetails;
UIViewController *RootViewController;
NSMutableData *responseData;
}
#property (nonatomic, retain) IBOutlet UITableView *tblView;
#property (nonatomic, retain) NSArray *teamStatusMutableArray;
#property (nonatomic, retain) NSMutableArray *dummyMutableArrayTimeQuota;
#property (nonatomic, retain) NSArray *teamStatusDataSection;
#property (nonatomic, retain) NSDictionary *teamStatusDictSectionOne;
#property (nonatomic, retain) IBOutlet UIViewController *RootViewController;
#property (nonatomic, retain) IBOutlet UIViewController *EmployeeDetails;
- (void)GetTeamStatus: id;
- (void)BuildDataSource: id: (NSArray*)teamStatusData;
#end

Hey the array returned by the web service contains dictionaries, which is obvious.
Instead of using different arrays for each property, you can create a class which extends NSObject and convert each dictionary so that you will have the objects inside an array instead of dictionaries. In this case:
#interface OrgUnit:NSObject {
NSString *FirstName;
NSNumber *Id;
bool IsPresent;
NSString *LastName;
}
//And all the properties here
After this you can convert dictionaries into object by using
OrgUnit *unit = [[OrgUnit alloc] init];
[unit setValuesForKeysWithDictionary:dictionary];
PS: The variable names in the object should be same as that of the keys in dictionary

I´ve found a solution.
This is the way I get to the data:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
NSDictionary *dictionary = [teamStatusMutableArray objectAtIndex:indexPath.section];
NSArray *teamStatus = [dictionary objectForKey:#"OrgUnits"];
NSEnumerator *e = [teamStatus objectEnumerator];
id object;
int i = 0;
while (object = [e nextObject]) {
if(i == indexPath.row)
{
NSString *firstname = [object valueForKey:#"Firstname"];
NSString *lastname = [object valueForKey:#"Lastname"];
NSString *fullname = [NSString stringWithFormat:#"%#%#%#", lastname, #", ", firstname];
cell.textLabel.text = fullname;
bool isPresent = [object valueForKey:#"IsPresent"];
if(isPresent == true)
{
cell.imageView.image = [UIImage imageNamed:#"GreenBall.png"];
}
else
{
cell.imageView.image = [UIImage imageNamed:#"RedBall.png"];
}
break;
}
i++;
}
[aiActivity stopAnimating];
self.aiActivity.hidden = true;
return cell;
}

Could be just a typo.
Change this:
teamStatusDictSectionOne = [NSDictionary dictionaryWithObject:teamStatusDataSection forKey:#"OrgUnits"];
To this:
teamStatusDictSectionOne = [NSDictionary dictionaryWithObjects:teamStatusDataSection forKey:#"OrgUnits"];
The change is -dictionaryWithObjects. Plural. Obj-C is kinda finicky about that stuff.
Also, you are referencing indexPath.section when you build the individual cells. I think you should be referencing the row for the cell. The row should correlate to your array index.
NSInteger row = [indexPath row];
NSDictionary *dictionary = [teamStatusMutableArray objectAtIndex:row];

Related

UITableView and alphabetical order

In my app I parse an XML file then I would like to show the entry of this file in a UITableView. I found on the web how to make section in alphabetical order (like iPhone contacts), it works fine with my app. When i tap on a row in my tableview I want to display another ViewController, in which I will find some information about the row I tapped, but I'm having some problem: when I tap on a row the variable indexPath.row refers to the section and the information in new view controller aren't right. I will post here some screenshot to show you want I'm trying to explain.
In the following pictures you can see how the app should work:
In the following pictures you can see the error of my app:
You can see that in picture 1 the name is the same and in picture 2 you can see that the name it's wrong. I guess it depend on the variable indexPath.row. I will post here the code to create and populate the tableview:
#import "TableWasteViewController.h"
#import "WasteXmlParser.h"
#import "WasteDetailViewController.h"
#interface TableWasteViewController ()
#property(nonatomic,strong)NSArray *arrayWastes;
#property(nonatomic,strong)NSMutableArray *typeOfWaste;
#property(nonatomic,strong)NSMutableArray *typeOfBin;
#property(nonatomic,strong)NSMutableArray *indexWastes;
#property(nonatomic,strong)NSMutableArray *typeOfWasteBackup;
#end
#implementation TableWasteViewController
- (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.
WasteXmlParser *parser = [[WasteXmlParser alloc]init];
[parser parseWasteXml];
self.arrayWastes = [[NSArray alloc]init];
self.arrayWastes = [parser.arrayWastes mutableCopy];
self.indexWastes = [[NSMutableArray alloc]init];
self.typeOfWaste = [[NSMutableArray alloc]init];
self.typeOfBin = [[NSMutableArray alloc]init];
for (int i = 0; i < [self.arrayWastes count]; i++) {
[self.typeOfWaste addObject:[[self.arrayWastes objectAtIndex:i] objectForKey:#"type"]];
[self.typeOfBin addObject:[[self.arrayWastes objectAtIndex:i]objectForKey:#"place"]];
}
for (int i = 0; i < [self.typeOfWaste count]-1; i++) {
char alphabet = [[self.typeOfWaste objectAtIndex:i] characterAtIndex:0];
NSString *uniChar = [NSString stringWithFormat:#"%c", alphabet];
if (![self.indexWastes containsObject:uniChar]) {
[self.indexWastes addObject:uniChar];
}
}
self.typeOfWasteBackup = [self.typeOfWaste mutableCopy];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.indexWastes count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [self.indexWastes objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *alphabet = [self.indexWastes objectAtIndex:section];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#",alphabet];
NSArray *wastes = [self.typeOfWaste filteredArrayUsingPredicate:predicate];
return [wastes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
UIFont *myFont = [UIFont fontWithName:#"Arial" size:14.0];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString *alphabet = [self.indexWastes objectAtIndex:[indexPath section]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSArray *wastes = [self.typeOfWaste filteredArrayUsingPredicate:predicate];
if ([wastes count] > 0) {
NSString *cellValue = [wastes objectAtIndex:indexPath.row];
cell.textLabel.font = myFont;
cell.textLabel.numberOfLines = 2;
cell.textLabel.text = cellValue;
}
return cell;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return self.indexWastes;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSIndexPath *indexPath = [self.tableWaste indexPathForSelectedRow];
WasteDetailViewController *vc = segue.destinationViewController;
vc.typeOfWaste = [self.typeOfWaste objectAtIndex:indexPath.row];
vc.typeOfBin = [self.typeOfBin objectAtIndex:indexPath.row];
vc.urlPic = [self.arrayWastes[indexPath.row]objectForKey:#"imgUrl"];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (IBAction)backToHome:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
I hope you can help me to fix this issue. Thank you
Rows are indexed by section, i.e. the first item in each section has indexPath.row == 0. So in order to look up values in your flattened vc.typeOfWaste and vc.typeOfBin arrays, you're going to need to do something along the lines of your numberOfRowsInSection method, where you filter the flattened array by the alphabet character and then get the item of the filtered array using indexPath.row.
Overall, this approach seems rather messy, having to filter your data repeatedly. Your data structures don't map well to the problem being solved. I would recommend using the TLIndexPathTools data model TLIndexPathDataModel because it's specifically designed for tables and collection views, can organize your data into sections, and can look up items by index path. Would be happy to walk you through a refactor if you like.
It's because the arrays that you're using to pass the data to the WasteDetailViewController, which are "typeOfWaste, typeOfBin, and urlPic" aren't sorted. The sorted array is called "wastes", but it is only available within the numberOfRowsInSection and the cellForRowAtIndexPath methods. You need to be passing the data in the wastes array forward, so rather than sorting the wastes array all the time, just sort it once after you've loaded it.
Add this property:
#interface TableWasteViewController ()
#property (strong, nonatomic) NSArray *sortedWastes;
#end
Now in viewDidLoad
NSString *alphabet = [self.indexWastes objectAtIndex:section];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#",alphabet];
self.sortedWastes = [self.typeOfWaste filteredArrayUsingPredicate:predicate];
Finally, in prepareForSegue
vc.typeOfWaste = [self.sortedWastes objectAtIndex:indexPath.row];
Your problems all stem from the fact that you are displaying a sorted array, but the array that you are using to pass the data forward is the unsorted array, so the indexPath is completely useless.
Furthermore, your typeOfBin and urlPic are going to be wrong as well. You need to find some way to link all three of your arrays together, so that when you sort one, you sort them all. The method above only keeps your typeOfWaste array sorted.
I also faced this issue few days ago...u need to make one class set properties whatever you want and then add that object in one array after that u can sort array on one property then whole array will be sorted
#import <Foundation/Foundation.h>
#interface HomeFeed : NSObject
#property (nonatomic, copy) UIImage *ItemImage;
#property (nonatomic, copy) NSString *ItemTitle;
#property (nonatomic, copy) NSString *ItemDate;
#property (nonatomic, copy) NSString *ItemDescription;
#property (nonatomic, copy) NSString *ItemHours;
#property (nonatomic, copy) NSString *ItemID;
#property (nonatomic, copy) NSString *itemDetailUrl;
#property (nonatomic, copy) NSString *itemPerson;
#property (nonatomic, copy) NSString *itemThumbUrl;
#property (nonatomic, assign) int ItemDuration;
#end
#import "HomeFeed.h"
#implementation HomeFeed
#synthesize ItemTitle=_ItemTitle, ItemDate=_ItemDate, ItemImage=_ItemImage,ItemID=_ItemID,ItemDuration=_ItemDuration,ItemDescription,ItemHours=_ItemHours,itemDetailUrl,itemPerson,itemThumbUrl;
#end
NSArray*arr=[responseString JSONValue];
NSLog(#"Json Dictionary speakersss : %#",arr);
NSLog(#"Json arr count speaker : %i",arr.count);
for (int i=0; i<arr.count; i++) {
NSDictionary *dict=[[ NSDictionary alloc]init];
dict=[arr objectAtIndex:i];
HomeFeed *feed = [[HomeFeed alloc] init];
feed.ItemTitle = [NSString stringWithFormat:#"%#%#%#",[dict objectForKey:#"firstName"],#" ",[dict objectForKey:#"lastName"]];
feed.ItemDuration = [[NSString stringWithFormat:#"%#", [dict objectForKey:#"count"]] intValue];
feed.itemDetailUrl=[dict objectForKey:#"detailsUrl"];
[self.itemsDataArray addObject:feed];
[itemTitle addObject:feed.ItemTitle];
}
HomeFeed *feed = [[HomeFeed alloc] init];
NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:#"ItemTitle" ascending:YES];
[self.itemsDataArray sortUsingDescriptors:[NSArray arrayWithObject:sorter]];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SpeakersCustomCell"];
cell.selectionStyle = NO;
cell.accessoryType = NO;
HomeFeed *feed = [self.itemsDataArray objectAtIndex:indexPath.row];
UIImageView *arrow = (UIImageView *)[cell viewWithTag:3];
arrow.image = [UIImage imageNamed:#"accessory.png"];
UILabel *lblLeft = (UILabel *)[cell viewWithTag:1];
UILabel *lblRight = (UILabel *)[cell viewWithTag:2];
lblLeft.text=feed.ItemTitle;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
HomeFeed *feed=(HomeFeed*)[self.itemsDataArray objectAtIndex:indexPath.row];
self.onlinDetail.strUrl=feed.itemDetailUrl;
NSString *key = #"OrientationStringValue";
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:feed.itemDetailUrl forKey:key];
[[NSNotificationCenter defaultCenter] postNotificationName:#"NotifSpeaker1" object:nil userInfo:dictionary];
}

NSCoding help very strange error access to deallocated instance

In my code I store in the memory my array... To obtain it without make an HTML Request.
the first time, when I populated my array everything is ok... the problems show up when I load array from the memory and load them in a table.
That's the class
#interface SubscriptionArray : NSObject{
NSString *title;
NSString *source;
NSString *htmlUrl;
NSInteger count;
}
#property (nonatomic,retain) NSString *title;
#property (nonatomic,retain) NSString *source;
#property (nonatomic,retain) NSString *htmlUrl;
#property (nonatomic) NSInteger count;
#end
#import "SubscriptionArray.h"
#implementation SubscriptionArray
#synthesize title,source,htmlUrl,count;
-(void)dealloc{
[title release];
[source release];
[htmlUrl release];
}
#pragma mark NSCoding
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
title = [[decoder decodeObjectForKey:#"title"] retain];
source = [[decoder decodeObjectForKey:#"source"] retain];
htmlUrl = [[decoder decodeObjectForKey:#"htmlUrl"] retain];
count = [decoder decodeIntegerForKey:#"count"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
if (title) [encoder encodeObject:title forKey:#"title"];
if (source) [encoder encodeObject:source forKey:#"source"];
if (htmlUrl) [encoder encodeObject:htmlUrl forKey:#"htmlUrl"];
if (count) [encoder encodeInteger:count forKey:#"count"];
}
The array is declared in the delegate (to share with 3 different classes) as
NSMutableArray *onlySubsriptions; #property(nonatomic, retain)
NSMutableArray *onlySubsriptions;
And I load it in this way
[onlySubsriptions removeAllObjects];
self.onlySubsriptions = [NSKeyedUnarchiver unarchiveObjectWithFile:fullFileName];
And I received an error in the cellForRowAtIndexPath
for example I'm sure that I have 2 elements, the cellForRowAtIndexPath throws an exception when it start to load the 1st element (element 0)... it says deallocated instance.
I'm sure that the problem is on the encoding because the 1st time when I get the array everything is fine... Problems show up only when the next time I load my array that I store locally.
**** MORE INFO ABOUT ******
**** cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
TDBadgedCell *cell = [[[TDBadgedCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
SubscriptionArray * element=[[SubscriptionArray alloc]init];
if (indexPath.section==0) {
NSLog(#"CASO SPECIALELEMENTS");
element =[delegate.reader.specialElements objectAtIndex:[indexPath row]];
}
if (indexPath.section==1) {
NSLog(#"CASO CATEGORIA");
element =[delegate.reader.categories objectAtIndex:[indexPath row]];
}
if (indexPath.section==2) {
NSLog(#"CASO SUBSCRIPTIONS");
element =[delegate.reader.onlySubsriptions objectAtIndex:[indexPath row]];
}
To deal with this kind of exception, you can use malloc instrument to find out the zombie and fix it.
Product > Profile will launch Instruments and then you there should be a "Trace Template" named "Malloc". This question may be useful for you.

EXC_BAD_ACCESS on a NSMutableArray that contains a custom class

I receive I EXC_BAD_ACCESS but i can't understand why.
this is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
TDBadgedCell *cell = [[[TDBadgedCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
SubscriptionArray * element =[reader.subscriptions objectAtIndex:[indexPath row]];
[cell.textLabel setText:element.title]; // <--- error at this line of code
return cell;
}
reader.subscritions is NSMutableArray that contains 81 elements ( I'm sure verificated with a NSLog) but when I try to get set the title I have this error... why?
SubscritionArray is a custom class that contains 3 string and 1 int.
Custom class:
header
#import <Foundation/Foundation.h>
#interface SubscriptionArray : NSObject{
NSString *title;
NSString *source;
NSString *htmlUrl;
NSInteger count;
}
#property (nonatomic,retain) NSString *title;
#property (nonatomic,retain) NSString *source;
#property (nonatomic,retain) NSString *htmlUrl;
#property (nonatomic) NSInteger count;
#end
implementation:
#import "SubscriptionArray.h"
#implementation SubscriptionArray
#synthesize title,source,htmlUrl,count;
-(void)dealloc{
[title release];
[source release];
[htmlUrl release];
}
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
title = [[decoder decodeObjectForKey:#"title"] retain];
source = [[decoder decodeObjectForKey:#"source"] retain];
htmlUrl = [[decoder decodeObjectForKey:#"htmlUrl"] retain];
//count = [decoder decodeIntForKey:#"count"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
if (title) [encoder encodeObject:title forKey:#"title"];
if (source) [encoder encodeObject:source forKey:#"source"];
if (htmlUrl) [encoder encodeObject:htmlUrl forKey:#"htmlUrl"];
//if (count) [encoder encodeInteger:count forKey:#"count"];
}
#end
EDIT
Tha's what I get
* -[__NSArrayM objectAtIndex:]: message sent to deallocated instance 0xe5a8260
And that's how I set the NSMutableArray
subscriptions = [[NSMutableArray alloc]init];
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//make a file name to write the data to using the
//documents directory:
NSString *fullFileName = [NSString stringWithFormat:#"%#/subscriptions", documentsDirectory];
[subscriptions removeAllObjects];
subscriptions = [NSKeyedUnarchiver unarchiveObjectWithFile:fullFileName];
I'd venture to say that your array of subscription elements isn't matching up with your row indexes (just a guess). Suggest that you set a debugger breakpoint immediately after you've declared 'element' and before you attempt to set the label. You should be able to see if you have actually obtained one of your SubscriptionArray objets...
The mutable array in reader.subscriptions is getting deallocated before you attempt to reference it in tableView:cellForRowAtIndexPath:. Make sure that the subscriptions array is properly retained or copied by the reader, and that you're not overreleasing it by sending an extra release or autorelease message somewhere. It might help to post the relevant code from the class of the reader instance.

NSArray With NSString Is This Even Possible?

I am trying to build a Grouped Sectioned View. I want to set an array as an object in the dictionary but I came across the empty array Issues.
Is this Even possible????? Is There a trick ????
#import "RootViewController.h"
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Get the specific Node for this row.
Nodes *nodes = (Nodes *)[nodesMArray objectAtIndex:indexPath.row];
// Create the Details View Controller and initialize it.
nodesDetailView *viewController = [[nodesDetailView alloc] initWithStyle:UITableViewStyleGrouped ];
[[self navigationController] pushViewController:viewController animated:YES];
// Set the title of the view to the nodes name
viewController.title = [nodes computer_name];
//Information
//Network Data
viewController.ipaddress= [nodes ipaddress];
viewController.subnet_mask= [nodes subnet_mask];
viewController.gateway= [nodes gateway];
viewController.domain_name= [nodes domain_name];
}
#import "nodesDetailViewController. h
#interface nodesDetailView : UITableViewController{
//Network Data
NSString *ipaddress;
NSString *subnet_mask;
NSString *gateway;
NSString *domain_name;
//Grouped
NSMutableArray *Keys;
NSMutableDictionary *Contents;
}
#property (nonatomic, retain) NSMutableArray *Keys;
#property (nonatomic, retain) NSMutableDictionary *Contents;
#property (nonatomic, retain) NSString *ipaddress;
#property (nonatomic, retain) NSString *subnet_mask;
#property (nonatomic, retain) NSString *gateway;
#property (nonatomic, retain) NSString *domain_name;
#end
#import "nodesDetailViewController. m
#synthesize .......
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
NSMutableArray *keys = [[NSMutableArray alloc] init];
NSMutableDictionary *contents = [[NSMutableDictionary alloc] init];
NSString *network = #"Network Data";
NSString *product = #"Product Details";
//IS THIS POSSIBLE ??????? Because I get An Empty array
[contents setObject:[NSArray arrayWithObjects: ipaddress,subnet_mask, gateway, domain_name, nil] forKey:network];
return self;
}
Thank You In Advance.
All of those strings that you are adding to the array haven't even been allocated/initialized yet. That's why the array is empty. You can't just go: NSString *emptyString; and then go: [myArray addObject:emptyString];. Your strings are all empty.
Check the values u are passing from the table view. They maybe nil. I just used this much of data and i m getting correct NSLog.
NSMutableDictionary *contents = [[NSMutableDictionary alloc] init];
NSString *my = #"kk";
NSString *my1 = #"polko";
[contents setObject:[NSArray arrayWithObjects: my1,my, nil] forKey:#"o"];
NSLog(#"%#" , contents);
For Those Who are wondering: Problem Solved My code was fine. the problem was :
it was in the wrong place.
The Code Supposed to be in - (void)viewDidLoad and not in - (id)initWithStyle:
I want to thank everybody who took the time to look in to it.
I have no idea why i put the code there to begin with.
Thanx Again

inserting NSURL or integer in NSDictionary

i have a class 'book.h' in which i have declared
Book.h
NSInteger WeatherID;
NSString *Description;
NSURL *PictureURL;
BookDetailview.h
#import <UIKit/UIKit.h>
#class Book, XMLAppDelegate;
#interface BookDetailViewController : UIViewController
{
IBOutlet UITableView *tableView;
XMLAppDelegate *appDelegate;
Book *aBook; //creating object of 'Book-class'
NSMutableDictionary *EmpDictionary;
NSMutableArray *EmpArray;
}
#property (nonatomic, retain) Book *aBook;
#property (nonatomic, retain) NSMutableArray *EmpArray;
#end
BookDetailView.m
(UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"creation of cell");
static NSString *CellIdentifier = #"Cell";
ImageCell *cell = (ImageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // creating cell from ImageCell.m
NSLog(#"calling image class");
if (cell == nil) {
cell = [[[ImageCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; // allocating with frame
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSLog(#"abook ...pictutre url......%#" , aBook.PictureURL);
EmpDictionary=[[NSMutableDictionary alloc]init];
[EmpDictionary setValue:aBook.Description forKey:#"Description"];
[EmpDictionary setValue:aBook.PictureURL forKey:#"PictureURL"];
[EmpDictionary setValue:aBook.WeatherID forKey:#"WeatherID"];
EmpArray=[[NSMutableArray alloc]init];
[EmpArray addObject:EmpDictionary];
NSDictionary *itemAtIndex = [self.EmpArray objectAtIndex:indexPath.row];
[cell setData:itemAtIndex]; //call to 'setData' meyhod to ImageCell.m
NSLog(#"set text of a cell");
return cell;
}
ImageCell.m
-(void)setData:(NSDictionary *)dic {
self.titleLabel.text = [dic objectForKey:#"Description"];
self.urlLabel.text = [dic objectForKey:#"PictureURL"];
self.itemID = (NSInteger)[dic objectForKey:#"WeatherID"];
NSLog(#"setting objects for keys");
// setting up the imageView now
self.imageView.image = [UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString: [dic objectForKey:#"PictureURL"]]]];
NSLog(#"setting of image");
}
[dict setValue:value forKey:key];
[dict setObject:object forKey:key];
NSDictionary *dict1 = [[NSDictionary alloc] initWithObjectsAndKeys:
#"val1", #"key1", #"val2", #"key2", #"val3", #"key3",#"val4", #"key4",#"val5", #"key5",nil];