Multilevel JSON Dictionary - can't extract key into new dictionary - objective-c

I've been stuck on a problem for a few days now. I have searched the internet and found many answers, but nothing that seems to work - I may not grasp how to modify my own code.
I have a JSON connection which I make a dictionary. This all works very well when I dont have a multilevel dictionary, but as soon as I have:
{
"Table": [
{
"MENUID": 1072.0,
"MENUDESC": "HOME ",
"PARENTMENUID": null,
"NAVIGATETO": "content.aspx?item=1072&pid=0",
"NAVIGATETO2": "default.aspx?item=1072&pid=0",
"PROTECTED": null,
"parentmenuid2": null
},
{
"MENUID": 1073.0,
"MENUDESC": "PRODUCTS & SERVICES",
"PARENTMENUID": null,
"NAVIGATETO": "#",
"NAVIGATETO2": "default.aspx?item=1073&pid=0",
"PROTECTED": null,
"parentmenuid2": null
}
]
}
I adapt my code as follows:
- (void)fetchTweets
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: #"http://adhoc.nyxtek.co.za/spfjsonws/default2.aspx"]];
NSError* error;
menuItems = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
NSArray * allKeys = [menuItems allKeys];
NSLog(#"Count : %d", [allKeys count]);
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
});
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return menuItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TweetCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *tweet = (NSDictionary *)[menuItems objectForKey:#"Table"];
NSArray * allKeys = [tweet allKeys];
NSLog(#"Count : %d", [allKeys count]);
//NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
NSString *text = [tweet objectForKey:#"MENUDESC"];
NSString *name = [tweet objectForKey:#"MENUID"];
cell.textLabel.text = text;
cell.detailTextLabel.text = [NSString stringWithFormat:#"by %#", name];
return cell;
}
Specifically this line of code is not working:
NSDictionary *tweet = (NSDictionary *)[menuItems objectForKey:#"Table"];
My first count of the outer dictionary is 1 which is correct, but my second count of the new above dictionary is 0 which is wrong.
I have applied much of this from researching previous questions as I understand the importance of research, but I still cant seem to find a specific fault.
Any assistance would be appreciated.

Table is an array (of dictionaries):
"Table": [
...
]
So the code should be:
NSArray *tweet = (NSArray *)[menuItems objectForKey:#"Table"];

Related

objectatindex outside of loop?

This is a question hard to ask but I'm going to give it a shot anyways. I'm trying to retrieving the contents of an NSDictionary outside of the UITableCell loop. Right now, when I do retrieve its content via:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
everything works fine. But outside of that loop, in a void function of its own, the number retrieved is 0.
- (void)getVideoList{
NSString *ensdsds = #"z9yDgV3ONSU";
for (int i=0; i< [self.youtubePaginator.results count]; i++){
NSDictionary *photoshoots = [self.youtubePaginator.results objectAtIndex:i];
NSString * videoId = photoshoots[#"videoID"];
NSLog(#"Newly %#: ", videoId);
NSString *urlStrings = [NSString stringWithFormat:#"https://www.googleapis.com/youtube/v3/videos?part=id%%2C+snippet%%2C+contentDetails%%2C+statistics&id=%#&key=78587868", videoId];
NSLog(#"Arries %#", urlStrings);
NSURL *urlstats = [NSURL URLWithString:urlStrings];
NSURLRequest *requeststats = [NSURLRequest requestWithURL:urlstats];
AFHTTPRequestOperation *operationtwo = [[AFHTTPRequestOperation alloc] initWithRequest:requeststats];
operationtwo.responseSerializer = [AFJSONResponseSerializer serializer];
[operationtwo setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operationtwo, id responseObjected)
{
NSDictionary *itemed = [responseObjected objectForKey:#"items"];
for (NSDictionary *itemest in itemed )
{
YouTubeVideo *youTubeVideo = [[YouTubeVideo alloc] init];
NSDictionary* stats = [itemest objectForKey:#"statistics"];
youTubeVideo.likesCount = [stats objectForKey:#"likeCount"];
youTubeVideo.viewsCount = [stats objectForKey:#"viewCount"];
NSDictionary* channelInfo = [itemest objectForKey:#"snippet"];
youTubeVideo.channelInfo = [channelInfo objectForKey:#"channelId"];
youTubeVideo.videoUploader = [channelInfo objectForKey:#"channelTitle"];
NSLog(#"True To: %#", youTubeVideo.videoUploader);
[self.thunder addObject:youTubeVideo];
}} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error loading %#", error);
}];
[operationtwo start]; }
}
The above code returns nothing. How do I incorporate NSIndexPath in the void function and still be able to call [self getVideoList]; in viewDidLoad.
Hope that makes sense? :/
You can get the imageURL in getVideoList by passing NSIndexPath as a parameter , you just need to create a global NSString object if you want to access it globally or you can return extracted imageURL as a return value.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * imageURL = [self getVideoList:indexPath];
// Write your code to perform operation with the image URL.
}
Here is the getVideoList method
- (NSString *)getVideoList:(NSIndexPath *)indexPath{
NSDictionary *photoshoots = [self.youtubePaginator.results objectAtIndex:indexPath.Row];
NSString * imageURL = photoshoots[#"avatar_url"];
NSLog(#"Newly %#: ", imageURL);
NSLog(#"To find us: [%d]:%#",i,self.youtubePaginator.results[i]);
return imageURL;
}
You can update the code as per your requirement.

Array reduplication not working

Xcode problem. I have a nsmutablearray that is pulling json objects. Example Company: Name, state, address, phone number, etc.
I am pulling the info just fine. And I want to display 1 of each state in a table view. It works fine but shows multibles of the same state. But I only want to show 1 of each state. I am using some code but it does not return any states. I have seen a lot of examples and this should work but it returns nothing. If I skip this code below it does show all states. i have also tried a for loop. And tried array to NSSet. Nothing is working. Any Ideas???
My problem is with this code...
//Create states only array...remove duplicate states here
NSArray *statesArray = [companies valueForKeyPath:#"#distinctUnionOfObjects.state"];
return statesArray;
Here is my whole code. Please help been struggling with this for a week.
#interface StatesTableViewController ()
#property (nonatomic) NSString *name;
#property (nonatomic) NSString *state;
#end
#implementation StatesTableViewController
NSArray *companies;
NSArray *statesArray;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *address = #"http://www.companiesFeed";
NSURL *url = [[NSURL alloc] initWithString:address];
//laod the data on a background queue..
//if we were connecting to a an online url then we need it
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
companies = [self readCompanies:url];//, statesSet = [self readCompanies:url];
//now that we have the data, reload the table data on the main ui thread
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:YES];
});
}
//new code
- (NSArray *)readCompanies:(NSURL *)url {
//create a nsurlrequest with the given Url
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:
NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:30.0];
//get the data
NSURLResponse *response;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
//now create a nsdictionary from the json data
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data
options:0 error:nil];
//create a new array to hold the comanies
NSMutableArray *companies = [[NSMutableArray alloc] init];
//get an array of dictionaries with the key "company"
NSArray *array = [jsonDictionary objectForKey:#"companies"];
//iterate throught the array of dictionaries
for (NSDictionary *dict in array) {
//create a new company object with information in the dictionary
Company *company = [[Company alloc] initWithJSONDictionary:dict];
//add the Company object to the array
[companies addObject:company ];
}
//Create states only array...remove duplicate states here
NSArray *statesArray = [companies valueForKeyPath:#"#distinctUnionOfObjects.state"];
return statesArray;
//return companies;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark -table view controller methods
//change uniqueValue errors to companies
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
//return[companies count];
return [statesArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"CellIDState";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil){
//single line on table view
//cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellID];
// dual line on table view
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
}
//edit single state
//Company *company = [companies objectAtIndex:indexPath.row];
Company *company = [statesArray objectAtIndex:indexPath.row];
//cell.textLabel.text = company.company_id;
cell.textLabel.text = company.state;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#",company.companyName];
//adds cheveron to tableviewl
[cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
#pragma mark - navigation
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
}
#end
I was able to get the unique list of states by using a predicate and a block to check a set for existing states. Like so:
NSMutableArray *statesArray = [NSMutableArray array];
[companies filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
Company *dict = (Company *)evaluatedObject;
BOOL seen = [statesArray containsObject:dict];
if (!seen) {
[statesArray addObject:dict];
}
return !seen;
}]];
NSLog(#"unique states: %#", statesArray);
Where the companies array looks like this:
{[{
"company_id": "22",
"entityformSubmissionID": "22",
"companyName": "house of waffles",
"companySlogan": " where your home is!",
"address1": "123 here",
"address2": "thre",
"city": "everywhere",
"state": "CA",
"zipCode": "94531",
"phoneNumber": "777-777-7777",
"email": "test#test.com",
"additionalCompanyInfo": "all additional company info is going here",
"sales": "There are no sales!",
"rentalTerms": "Terms is dont break our stuff jerks!",
"companyLogo": "/16x16icon.png"
}]

Xcode find table view section row on detail text label

I have an index set up with my table and I am able to return the correct arrays for the textLabel.text according to the section header. My problem is I have an a separate array that i need to return in the detailTextLabel.text.
It just repeats in each section starting from the first index from the first section. For example:
A
Apple
apple
Alligator
alligator
B
Ball
apple
Bat
alligator
I've generated index characters and table headers. This is what I have to return the cell.
NSString *alphabet = [arrayIndex objectAtIndex:[indexPath section]];
//---get all of First array's beginning with the letter---
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSArray *firstArray = [First filteredArrayUsingPredicate:predicate];
NSArray *secondArray = [Second filteredArrayUsingPredicate:predicate];
if ([FirstArray count]>0) {
//---extract the relevant state from the states object---
NSString *cellValue = [firstArray objectAtIndex:indexPath.row];
//<--This line throws and error assuming it is trying to find the first letter to return the detail text -->
NSString *cellValueA = [secondArray objectAtIndex:indexPath.row];
//Returns value from first section and row in all section//
//NSString *cellValueA = [Second objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
cell.detailTextLabel.text = cellValueA;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
How do I find the matching row to the First Array to return the correct index in the Second Array. Any help would be much appreciated. Thank You :-)
FULL CODE
-(void)loadSQL {
// Path to the database
NSString* dbPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"DATABASE_NAME.sqlite"];
NSLog(#"databasePath: %#",dbPath);
sqlite3 *database;
NSString *firstString;
NSString *secondString;
// Open the database
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
NSString *querySQL = [NSString stringWithFormat:
#"SELECT * FROM songs WHERE items LIKE %# ", viewItems];
const char *sql = [querySQL UTF8String];
sqlite3_stmt *compiledStmt;
// Fetch all names
if (sqlite3_prepare_v2(database, sql, -1, &compiledStmt, NULL) == SQLITE_OK) {
// Append each name
while (sqlite3_step(compiledStmt) == SQLITE_ROW) {
const char* cFirst = (char*)sqlite3_column_text(compiledStmt, 2);
const char* cSecond = (char*)sqlite3_column_text(compiledStmt, 3);
if (cFirst == NULL)
// There should not be a NULL name
NSLog(#"Null name!!");
else {
firstString = [NSString stringWithUTF8String:cName];
secondString = [NSString stringWithUTF8String:cArtist];
[First addObject:firstString];
[Second addObject:secondString];
//[First release];
//[Second release];
}
}
sqlite3_finalize(compiledStmt); // Cleanup the statement
}
else {
NSLog(#"Error retrieving data from database.");
}
sqlite3_close(database);
}
else {
NSLog(#"Error: Can't open database!");
}
//Creating section with 1st letter of the First field//
for (int i=0; i<[First count]-1; i++){
//---get the first char of each state---
char alphabet = [[First objectAtIndex:i] characterAtIndex:0];
NSString *uniChar = [NSString stringWithFormat:#"%C", alphabet];
//---add each letter to the index array---
if (![arrayIndex containsObject:uniChar])
{
[arrayIndex addObject:uniChar];
}
}
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (searching)
return 1;
else
return [arrayIndex count];
}
//---set the title for each section---
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (searching)
return nil;
else
return [arrayIndex objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (searching)
return([searchedFirst count]);
else{
//return([First count]);
NSString *alphabet = [songIndex objectAtIndex:section];
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSArray *firstArray = [First filteredArrayUsingPredicate:predicate];
return [firstArray count];
}
}
//---set the index for the table---
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
if (searching) {
return nil;
}
return arrayIndex;
}
//return the cell info
- (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] autorelease];
if(searching) {
cell.textLabel.text = [searchedFirst objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [searchedSecond objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
else{
//---get the letter in the current section---
NSString *alphabet = [arrayIndex objectAtIndex:[indexPath section]];
//---get all states beginning with the letter---
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSArray *firstArray = [First filteredArrayUsingPredicate:predicate];
NSArray *secondArray = [Second filteredArrayUsingPredicate:predicate];
if ([songArray count]>0) {
NSString *firstValue = [firstArray objectAtIndex:indexPath.row];
NSString *secondValue = [secondArray objectAtIndex:indexPath.row];
cell.textLabel.text = firtValue;
cell.detailTextLabel.text = secondValue;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
return cell;
}
I am not sure I understand what you need, but if you are looking for the index in the array of a given object, then you can use:
indexOfObject:
Returns the lowest index whose corresponding array value is equal to a given object.
- (NSUInteger)indexOfObject:(id)anObject
(ref)
Answering the question from comments about restructuring....
First, create a custom class:
// CellLabels.h
#import <Foundation/Foundation.h>
#interface CellLabels : NSObject
#property (nonatomic, copy) NSString *firstText;
#property (nonatomic, copy) NSString *secondText;
#end
//CellLabels.m
#import "CellLabels.h"
#implementation CellLabels
#synthesize firstText = _firstText;
#synthesize secondText = _secondText;
#end
Instead of First and Second, create and initialize one NSMutableArray called cellData. Replace...
[First addObject:firstString];
[Second addObject:secondString];
...with...
CellLabels *labels = [[CellLabels alloc] init];
labels.first = firstString;
labels.second = secondString;
[cellData addObject:labels];
Then, your array filtering works by comparing "SELF.firstText" and your array references work by using:
CellLabels *labels = [filteredArray objectAtIndex:indexPath.row];
cell.textLabel.text = labels.firstText;
cell.detailTextLabel.text = labels.secondText;
(OK, I didn't check to make sure all that compiled but it should give you the idea.)

how to avoid NULL value in objective c

Please consider this code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSURL *url = [NSURL URLWithString:#"http://localhost/faq.php?faqType=2"]; // Modify this to
NSString *jsonreturn = [[NSString alloc] initWithContentsOfURL:url]; // Pulls the URL
NSLog(#"jsonreturn=%#",jsonreturn); // Look at the console and you can see what the restults are
NSData *jsonData = [jsonreturn dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSError *error = nil;
// In "real" code you should surround this with try and catch
NSDictionary *dict = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:&error];
if (dict)
{
rows = [[dict objectForKey:#"faq"] retain];
}
[jsonreturn release];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Configure the cell.
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *dict1 = [rows objectAtIndex:indexPath.row];
NSLog(#"%#", dict1);
cell.textLabel.text = [dict1 objectForKey:#"faqQues"];
}
//if it is not getting NULL value then UItableView is ok
{"faq":[{"faqQues":"this is mr.mack?"},{"faqQues":"is he good man?"}]}
//but if the data is like NULL
{"faq":[{"faqQues":"this is mr.mack?"},{"faqQues":null}]} // then it is creating EXEC_BAD_ACCESS error,
so how to avoid NULL or check null value, or how can i fix this issue?
You can query the value before using it.
if ([dict objectForKey:#"faqQues"] == [NSNull null]) {
// value is null, use your own value here
} else {
// good value to use
}
You can also do this while enumerating as well.
for (id value in dict) {
if (value == [NSNull null]) {
// null
}
}
The docs of TouchJSON state, that JSON null values are represented using the NSNull singleton (usually used to represent nil in collections - where nil is not allowed). So you have to check against [NSNull null].
But TouchJSON allows to override the default null object:
CJSONDeserializer *theDeserializer = [CJSONDeserializer deserializer];
theDeserializer.nullObject = NULL;
Details https://github.com/TouchCode/TouchJSON (see the "Avoiding NSNull values in output." section)
My fellow programmer Conrad Kramer actually came up with this: https://gist.github.com/3362607
I would change it to a function and replace NULL values with #""

Read plist data into a NSArray but get null

I got same warning here “local declaration hides instance variable” warning
but I got more problems...
Here is my code
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.someaddress.php"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
NSLog(#"\n\nCONNECTION: %#", theConnection);
NSData *returnData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil];
NSString *listFile = [[NSString alloc] initWithData:returnData encoding:NSASCIIStringEncoding];
NSMutableArray *plist = [[NSMutableArray alloc] init];
plist = [listFile propertyList];
NSLog( #"\n 1111 plist is \n%#", plist );
//I can get a plist format data here,But nothing in 2222
NSLog(#"Now you see me tableView Row Count");
NSLog(#"TOTAL PLIST ROW COUNT IS = %i", [plist count]);
// Return the number of rows in the section.
return [plist count];
}
and I got Warning here"Local declaration of 'plist' hides instance variable"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"LightCell";
LightCell0 *cell =(LightCell0 *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[LightCell0 alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell…
NSLog(#"Now you see me Load Data %i", indexPath.row);
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
//I try to get list data here But RETURN NULL
NSLog( #"\n 2222 plist is \n %#", plist);
switch (indexPath.row) {
case 0:
if ([plist valueForKey:#"nodeStatus"] == 0){
cell.lightImageView.image = [UIImage imageNamed:#"lightOff.png"];
NSLog(#"value for key Node Status : %#" ,[self.plists Valuefokey:#"nodeStatus"]);
//also return NULL !!
}
else if([self valueForKey:#"nodeStatus"] == 1){
cell.lightImageView.image = [UIImage imageNamed:#"lightOn.png"];
}
break;
case 1:
cell.lightLocation.text =[plist valueForKey:#"nodeName"] ;
if ([plist valueForKey:#"nodeStatus"] == 0){
cell.lightImageView.image = [UIImage imageNamed:#"lightOff.png"];
}
else if([plist valueForKey:#"nodeStatus"] == 1){
cell.lightImageView.image = [UIImage imageNamed:#"lightOn.png"];
};
break;
default:
break;
}
return cell;
}
This is the tow items I create in a plist
{
category = Light;
nodeID = 1;
nodeName = "Living Room";
nodeStatus = 0;
nodeTrigger = 0;
nodeType = "light_sw";
},
{
category = Light;
nodeID = 2;
nodeName = Kitchen;
nodeStatus = 0;
nodeTrigger = 0;
nodeType = "light_sw";
}
So that's my question ,Why can't I pass "plist" from
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
...
}
to
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
}
and I use NSMutableArray *plist = [[NSMutableArray alloc] init];
But still appear "Local declaration of 'plist' hides instance variable"
???
hope someone can figure out this problem
Best Regards !
and I got Warning here"Local declaration of 'plist' hides instance variable"
Well, then, you should fix that.
The warning is telling you that you've declared two variables named plist: One local to this instance method, and the other an instance variable. The local variable, having a narrower scope, hides the instance variable, so that when you refer to plist in the method, you are referring to the local variable. This means that you cannot access anything stored in the instance variable by another method, nor store anything in it for another method to retrieve.
The solution is either to kill off or to rename the local variable. If the latter is what you want, use Xcode's “Edit All in Scope” feature.
Also:
NSMutableArray *plist = [[NSMutableArray alloc] init];
plist = [listFile propertyList];
Creating the array on the first of those lines is redundant, because you immediately replace your pointer to that array with the pointer to another array, returned by propertyList. Thus, you never use and you leak the first array. You should at least cut out the creation of the first array, and you should probably cut out the entire first line (thereby cutting out both the first array and the local variable).
Here is the code I fix the warning ,the program can build without any warning
it also can display the result after reading the plist in tableview
1.Load the plist:
- (void)viewDidLoad {
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www. someaddress.php"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
NSData *returnData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil];
NSString *listFile = [[NSString alloc] initWithData:returnData encoding:NSASCIIStringEncoding];
plist = [listFile propertyList];
}
2.return the number to rows
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [plist count];
}
3.read the plist data to show result in cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"LightCell0";
LightCell0 *cell =(LightCell0 *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[LightCell0 alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell…
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
int i;
for (i=0; i<[plist count]; i++) {
//Get nodeName
if(indexPath.row == i)
{
cell.lightLocation.text = [[[plist objectAtIndex:i] valueForKey: #"nodeName"]description];
//Get Light Status to show the image
if ([[[plist objectAtIndex:i] valueForKey: #"nodeStatus"] intValue] == 0){
cell.lightImageView.image = [UIImage imageNamed:#"lightOff.png"];
}
else if([[[plist objectAtIndex:i] valueForKey: #"nodeStatus"] intValue] == 1){
cell.lightImageView.image = [UIImage imageNamed:#"lightOn.png"];
cell.lightSwitch.on=YES;
}
}
}
return cell;
}
It can get the right data ,and display the correct result in the tableview cells
BUTTTTTTT
If you scroll up the tableview,it's ok,when you on the top it will scroll down Automatically
When you "scroll down" the tableview,program crash ???
WHY ??? did I write anything wrong ???
plist = [listFile propertyList];=====>self.plist = [listFile propertyList];
THAT IS CORRECT