i'm just new to iOS Programming, so appreciate for any help. I'm trying to save text from UITextField to plist and load it in UITableView.
I've managed to make the text not overwritten, but when i try to load it in the table,the app crash.
I know the issue is when my table load the Data.plist since it's array in array.
But I still don't have to clue how to load my plist to table.
This is my code when save the text to plist.
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"Data.plist"];
NSMutableArray *array = [NSMutableArray arrayWithContentsOfFile:plistPath];
if (nil == array) {
array = [[NSMutableArray alloc] init];
}
NSMutableArray *list = [[NSMutableArray alloc]init];
[list addObject:resi.text];
[array addObject:list];
[array writeToFile:plistPath atomically: TRUE];
And this is the whole code for my table view
- (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.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (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 [array count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
ub;/{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
cell.textLabel.text = [self.array objectAtIndex:indexPath.row];
//cell.textLabel.text = [array objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
- (void)viewWillAppear:(BOOL)animated
{
// get paths from root direcory
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
// get documents path
NSString *documentsPath = [paths objectAtIndex:0];
// get the path to our Data/plist file
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"Data.plist"];
array = [NSMutableArray arrayWithContentsOfFile:plistPath];
[myHistoryTable reloadData];
}
cell.textLabel.text = [self.array objectAtIndex:indexPath.row];
Try this
//As you have NSArrays as objects in self.array.
NSArray *list = (NSArray *)[self.array objectAtIndex:indexPath.row];
if(list && [list count] > 0) { //to check and avoid any crash
cell.textLabel.text = [list objectAtIndex:0];
}
Related
So I have an application that have a tab in tab bar that display my TableView. Recently I modified it, and change my path for table from default
NSString *path = [[NSBundle mainBundle]pathForResource:#"Food" ofType"plist"];
replacing it with this:
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingString:#"food.plist"];
So my problem is, it work pretty fine when I am launching it on Simulator in XCode, but, when im trying to launch it on my iphone I cant see any TableView appear, just empty search bar and top navigation bar.
- (void)viewDidLoad {
[super viewDidLoad];
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingString:#"food.plist"];
listOfItems = [[NSMutableArray alloc]initWithContentsOfFile:path];
searchListOfItems = [[NSMutableArray alloc]init];
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 45)];
searchBar.barStyle = UIBarStyleBlackTranslucent;
searchBar.showsCancelButton = NO;
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
searchBar.delegate = self;
[[self tableView] setTableHeaderView:searchBar];
searching = NO;
letUserSelectRow = YES;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addProduct:)];
self.navigationItem.rightBarButtonItem = addButton;
[self.tableView reloadData];
}
- (void)hideModalViewController:(NSNotification *)notif {
[self dismissModalViewControllerAnimated:YES];
[self viewDidLoad];
}
- (void)addProduct:(UIBarButtonItem *)button {
BIDAddProductViewController *addProductVC = [[BIDAddProductViewController alloc]init];
[self presentModalViewController:addProductVC animated:YES];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(hideModalViewController:) name:#"HideModalViewController" object:addProductVC];
}
- (void)viewDidUnload {
[super viewDidUnload];
self.childController = nil;
self.tableView = nil;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSLog(#"Delete");
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingString:#"food.plist"];
NSMutableArray *listOfItemsToDelete = [[NSMutableArray alloc]initWithContentsOfFile:path];
[[[listOfItemsToDelete objectAtIndex:indexPath.section]objectForKey:#"Products"] removeObjectAtIndex:indexPath.row];
[listOfItemsToDelete writeToFile:path atomically:YES];
[self viewDidLoad];
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SectionsTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:SectionsTableIdentifier];
}
if(searching)
cell.textLabel.text = [[searchListOfItems objectAtIndex:indexPath.row]valueForKey:#"ProductName"];
else {
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *array = [[dictionary objectForKey:#"Products"]valueForKeyPath:#"ProductName"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
}
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (searching)
return 1;
else
return [listOfItems count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (searching)
return [searchListOfItems count];
else {
NSDictionary *dictionary = [listOfItems objectAtIndex:section];
NSArray *array = [dictionary objectForKey:#"Products"];
return [array count];
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if(searching)
return #"";
return [[listOfItems objectAtIndex:section]valueForKey:#"SectionName"];
}
#end
I want to mention that I did some things with Project and Target settings, but, before that issue everything was just fine. I have an iPhone 4s if thats matter. And I did cut lot of my code rows just for make it easier to read (removed searching methods and selecting row methods).
Please help me!
I think the problem is with -
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingString:#"food.plist"];
you need to use -
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:#"food.plist"];
I think your problem might be that
NSString *path = [[NSBundle mainBundle]pathForResource:#"Food" ofType"plist"];
searches "Food.plist" (notice the F)
and in
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingString:#"food.plist"];
you search for "food.plist" (notice low caps f)
Since your device is case sensitive and your Mac by default is not, I suspect that is your problem
I've been learning Objective C and the iPhone SDK gradually, and my current project involves building an application that stores numerical data (sports data). This is primarily for learning purposes, as there are multiple apps that do the same thing. Anyway, I've hit a bit of a snag. My intention is to have a list of players stored in a table and allow the user to add additional players.
At the moment, I have a button that when pressed, "Ninjas" will be added to the table. I've also enabled deleting in the table. Unfortunately, I can't seem to figure out how to save and load the data from a plist. I followed various tutorials and guides, but I can't figure out what's happening. My suspicion is I am loading the data from an empty array and adding to that array, but the array involving the data is a separate array from the plist. Unfortunately, I am a bit lost beyond that.
The data in my array is erased whenever I switch views. However, I've noticed that the data remains if I leave and come back, but not if I leave for a considerable amount of time, leave and restart the iphone, etc. This seems to occur even for apps that I have not worked on saving. Is this just a function of the iPhone holding onto data in case a user accidentally exits a program?
Hopefully I explained my issue somewhat tangibly. TL:DR version: I want to add data to an array, save it to a plist, and reload the data from the plist whenever the array is present on the screen. Code below is attempting to accomplish this, but it isn't succeeding.
Thanks
#import "RootViewController.h"
#import "NewPlayer.h"
#import "OptionsMenu.h"
#implementation RootViewController
#synthesize createdPlayers;
#synthesize listOfPlayers;
-(NSString *) pathOfFile{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentFolder = [paths objectAtIndex:0];
return [documentFolder stringByAppendingFormat:#"myfile.plist"];
}
-(void)applicationWillTerminate:(NSNotification*)notification{
NSMutableArray *array = [[NSMutableArray alloc]init];
[array writeToFile: [self pathOfFile] atomically:YES];
}
- (void)viewDidLoad
{
NSString *filePath = [self pathOfFile];
if ([[NSFileManager defaultManager]fileExistsAtPath:filePath]) {
NSArray *array = [[NSArray alloc]initWithContentsOfFile:filePath];
listOfPlayers.array = [array objectAtIndex:0];
[array release];
}
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:app];
[super viewDidLoad];
listOfPlayers = [[NSMutableArray alloc] init];
}
-(IBAction)AddButtonAction:(id)sender{
[listOfPlayers addObject:#"Ninjas"];
[createdPlayers reloadData];
}
-(IBAction)switchView:(id)sender{
OptionsMenu *second = [[OptionsMenu alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:second animated:YES];
}
-(IBAction)newView:(id)sender{
NewPlayer *second = [[NewPlayer alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:second animated: YES];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [listOfPlayers count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:15];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.textAlignment = UITextAlignmentCenter;
NSString *cellValue = [listOfPlayers objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSLog(#"delete section: %d rol: %d", [indexPath indexAtPosition:0], [indexPath indexAtPosition:1]);
[listOfPlayers removeObjectAtIndex:[indexPath indexAtPosition:1]];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert)
{
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
-(void)tableView:(UITableView *)listOfPlayers moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath{
}
-(void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc{
[createdPlayers release];
[listOfPlayers release];
[super dealloc];
}
#end
#import <UIKit/UIKit.h>
#interface RootViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
IBOutlet UITableView* createdPlayers;
IBOutlet UIButton* superCat;
NSMutableArray *listOfPlayers;
}
#property(nonatomic, retain) IBOutlet NSObject *listOfPlayers;
-(NSString *) pathOfFile;
-(void)applicationWillTerminate:(NSNotification*)notification;
-(IBAction)AddButtonAction:(id)sender;
-(IBAction)switchView:(id)sender;
-(IBAction)newView:(id)sender;
#property (nonatomic, retain) UITableView* createdPlayers;
#end
Code update 20th Dec:
-(NSString *) pathOfFile{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentFolder = [paths objectAtIndex:0];
return [documentFolder stringByAppendingFormat:#"myfile.plist"];
}
-(void)applicationWillTerminate:(NSNotification*)notification
{
[self.listOfPlayers writeToFile:[self pathOfFile] atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}
- (void)viewDidLoad
{
self.listOfPlayers = [[NSMutableArray alloc] init];
NSString *filePath = [self pathOfFile];
if ([[NSFileManager defaultManager]fileExistsAtPath:filePath]) {
NSArray *array = [[NSArray alloc]initWithContentsOfFile:filePath];
self.listOfPlayers = array;
[array release];
}
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:app];
[super viewDidLoad];
}
I don't know plist. But you can try use NSData
NSArray *array;
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
//Write data
[data writeToFile:filePath atomically:YES];
//Read data
NSFileManager *fileManager = [NSFileManager defaultManager];
NSData *oldData = [fileManager contentsAtPath:filePath];
NSArray *newArray = [NSKeyedUnarchiver unarchiveObjectWithData:oldData]
Welcome to the world of iOS programming. It's a lot of fun, but it can be frustrating, just as programming in any language can be. I feel your pain.
There are a number of things that I see:
In viewDidLoad, it appears that your code to read your file into an array is okay, but then it appears as if you're trying to assign only the first row of this array to your listOfPlayers. Try:
self.listOfPlayers = array;
array is an array, and so is your listOfPlayers. Also, using self will ensure that the synthesized setter is used, thus retaining your listOfPlayers when you release array.
In applicationWillTerminate, I believe you wish to write your listOfPlayers to a file, but what you are actually doing is allocating and initializing an empty array, and writing THAT to your file. Try:
-(void)applicationWillTerminate:(NSNotification*)notification
{
[self.listOfPlayers writeToFile: [self pathOfFile] atomically:YES];
}
I hope this helps!
There seems something wrong in your viewDidLoad
if ([[NSFileManager defaultManager]fileExistsAtPath:filePath]) {
NSArray *array = [[NSArray alloc]initWithContentsOfFile:filePath];
listOfPlayers.array = [array objectAtIndex:0];
.
.
}
.
.
.
listOfPlayers = [[NSMutableArray alloc] init];
You are accessing listOfPlayers before ever allocating it.
listOfPlayers.array is wrong as well
I've searched the web + stackoverflow for a solution.
I've an UITableView with information from a .plist file. The plist file have childs. Like the image.
plist http://www.afbeeldingenuploaden.nl/uploads/648899Schermafbeelding%202011-06-12%20om%2009.50.28.png
When i go to DetailView it will display information out of an UIPickerView that's included in the view. I want to display information from the child in the pickerview, the last level. Like the image.
plist1 http://www.afbeeldingenuploaden.nl/uploads/740501Schermafbeelding%202011-06-12%20om%2012.03.40.png
The problem is that i can't reach the last level from the plist in the UIPickerview with my code.
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSDictionary *dictionary = [tableDataSource objectAtIndex:row];
return [dictionary objectForKey:#"days"];
}
I use in my tableview for the detailview to reach the last level of the plist.
NSString currentLevel
Can anyone help me out with this, i'm stuck.
As I read the plist, it has an array of dictionaries first of which has a dictionary as one of its values at the second array level. Based on that, your method should be,
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSDictionary *dictionary = [tableDataSource objectAtIndex:row];
return [[dictionary objectForKey:#"New item"] objectForKey:#"days"];
}
This will work for the plist in the image. However if more members are added they should adhere to the same structure.
- (void)viewDidLoad {
[super viewDidLoad];
NSString *Path = [[NSBundle mainBundle] bundlePath];
NSString *DataPath = [Path stringByAppendingPathComponent:#"Diyet.plist"];
NSDictionary *tempDict = [[NSDictionary alloc] initWithContentsOfFile:DataPath];
self.data = tempDict;
[tempDict release];
NSArray *tempArray = [[NSArray alloc] init];
self.tableDataSource = tempArray;
[tempArray release];
self.tableDataSource = [data objectForKey:#"Bitki"];
pickerView.delegate = self;
pickerView.dataSource = self;
}
- (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];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Configure the cell.
cell.textLabel.text = [[tableDataSource objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.textLabel.numberOfLines = 2;
cell.textLabel.font = [UIFont boldSystemFontOfSize:16];
tableView.scrollEnabled = NO;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *dictionary = [tableDataSource objectAtIndex:indexPath.row];
NSArray *modelle = [dictionary objectForKey:#"DETAIL"];
if([modelle count] == 0) {
DetailController *dvController = [[DetailController alloc] initWithNibName:#"DetailController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:dvController animated:YES];
dvController.names.text = [dictionary objectForKey:#"name"];
} else {
BootViewController *rvController = [[BootViewController alloc] initWithNibName:#"BootViewController" bundle:[NSBundle mainBundle]];
rvController.currentLevel += 1;
rvController.currentTitle = [dictionary objectForKey:#"name"];
[self.navigationController pushViewController:rvController animated:YES];
rvController.tableDataSource = modelle;
[rvController release];
}
}
I have a problem, I make a TabBAr application (with navigationbar), the bar bar is a list of favorits stored in an array.
My problem is that if I change ViewController and add object to array, when I come back to UITableView it isn't reloaded...
This is the class:
-
(void)viewDidLoad {
[super viewDidLoad];
[self readArgFromDatabaseSottoArgomenti];
[self VisualizzaPreferiti];
}
- (void)viewWillAppear:(BOOL)animated {
[self.tableView reloadData];
}
-(void) readArgFromDatabaseSottoArgomenti {
databasePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"ARGOMENTI.sqlite"];
sqlite3 *databaseDesc;
// Init the argoments Array
arraySottoArgomenti = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &databaseDesc) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
// const char *sqlStatement = "select * from DESCRIZIONE ";
const char *sqlStatement = [[NSString stringWithFormat:#"SELECT * from DESCRIZIONE ORDER BY id"] UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(databaseDesc, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *aID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
NSString *aIDArgomento = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aDescrizione = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *aTesto = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
// Create a new argoments object with the data from the database
ContenutoObjectDescrizione *contenutoSottoArgomenti = [[ContenutoObjectDescrizione alloc] initWithName:aID idArgomento:aIDArgomento descrizione:aDescrizione testo:aTesto];
[arraySottoArgomenti addObject:contenutoSottoArgomenti];
[contenutoSottoArgomenti release];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(databaseDesc);
}
- (void) VisualizzaPreferiti {
int i;
NSUserDefaults *userPref = [NSUserDefaults standardUserDefaults];
array = [userPref objectForKey:#"array"];
NSLog(#"Retain Count %d Numero ID Array %d",[array retainCount],[array count]);
NSMutableArray *arrayOggettoPreferito;
arrayOggettoPreferito = [[NSMutableArray alloc] init];
ContenutoObjectDescrizione *oggetto = [[ContenutoObjectDescrizione alloc] init];
for (oggetto in arraySottoArgomenti) {
for (i=0; i<[array count]; i++) {
if ([[array objectAtIndex:i] intValue] == [oggetto.id intValue]) {
[arrayOggettoPreferito addObject:oggetto];
NSLog(#"ID %# IDMateria %# Titolo %#",oggetto.id,oggetto.idArgomento,oggetto.descrizione);
}
}
}
listaPref = arrayOggettoPreferito;
arrayOggettoPreferito=nil;
[arrayOggettoPreferito release];
[oggetto release];
}
#pragma mark -
#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 [listaPref count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
ContenutoObjectDescrizione *oggettoCercato = [[ContenutoObjectDescrizione alloc] init];
oggettoCercato = [listaPref objectAtIndex:[indexPath row]];
cell.textLabel.text = oggettoCercato.descrizione;
NSLog(#"%#",oggettoCercato.descrizione);
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
TestoViewController *testoViewController = [[TestoViewController alloc] initWithNibName:#"TestoView" bundle:nil];
[self.navigationController pushViewController:testoViewController animated:YES];
ContenutoObjectDescrizione *oggettoCercato = [[ContenutoObjectDescrizione alloc] init];
oggettoCercato = [listaPref objectAtIndex:[indexPath row]];
testoViewController.idPreferito = oggettoCercato.id;
testoViewController.title = oggettoCercato.descrizione;
NSString *descrizioneWeb = oggettoCercato.testo;
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[testoViewController.vistaWeb loadHTMLString:descrizioneWeb baseURL:baseURL];
[testoViewController release];
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
Simply calling reloadData doesn't make it do anything unless you update your datasource. In viewWillAppear, you will need to call VisualizzaPreferiti again before you call reloadData.
I have an array of dictionaries in an iOS .plist structured similar to the following:
<plist version="1.0">
<array>
<dict>
<key>name</key>
<string>Afghanistan</string>
<key>government</key>
<string>Islamic Republic</string>
<key>population</key>
<integer>29121286
</integer>
</dict>
<dict>
<key>name</key>
<string>Albania</string>
<key>government</key>
<string>Emerging Democracy</string>
<key>population</key>
<integer>2986952</integer>
</dict>
I am trying to load the <key>name</key> from each dictionary into an NSTableViewCell then display them all alphabetically in an NSTableView similar to the Contacts App in iOS.
Below are my ViewControllers .h and .m. The sort is working, but I am not able to load the results into the TableViewCells?
FirstViewController.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController <UITableViewDelegate,UITableViewDataSource>
{
NSArray *sortedCountries;
}
#property (nonatomic, retain) NSArray *sortedCountries;
#end
FirstViewController.m
#import "FirstViewController.h"
#implementation FirstViewController
#synthesize sortedCountries;
-(void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] pathForResource:#"countries"ofType:#"plist"];
NSArray *countries = [NSArray arrayWithContentsOfFile:path];
NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES] autorelease];
NSArray *sortedCountries = [[countries sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]] retain];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return 2;
}
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *country = [sortedCountries objectAtIndex:indexPath.row];
NSString *countryName = [country objectForKey:#"name"];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = countryName;
return cell;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[sortedCountries release];
[super dealloc];
}
#end
EDIT: Another question related to this here.
Add an ivar to your view controller's #interface in the header file:
#interface MyViewController : UITableViewController
{
...
NSArray *sortedCountries;
}
Add this code (to read and sort the plist by country name) to your view controller's initWith... method:
NSArray *countries = [NSArray arrayWithContentsOfFile: pathToPlist];
// Now the array holds NSDictionaries, sort 'em:
NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES] autorelease];
sortedCountries = [[countries sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]] retain];
Then use the following snippet to extract the values:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *country = [sortedCountries objectAtIndex:indexPath.row];
NSString *countryName = [country objectForKey:#"name"];
NSString *governmentType = [country objectForKey:#"government"];
NSSInteger population = [[country objectForKey:#"population"] integerValue];
// ... do something with countryName, governmentType, population
}
Don't forget to release sortedCountries:
- (void)dealloc
{
...
[sortedCountries release];
[super dealloc];
}
Create an NSArray for your file:
NSArray *iOSPlist = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"iOS" ofType:#"plist"]];
then in this method write after if (cell == nil){
}:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
cell.textLabel.text = [[iOSPlist objectAtIndex:indexPath.row] objectForKey:#"name"];
}
and don't forget to return [iOSPlist count] in the - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section method;
Here is an example pulling the version number out of the info.plist. Use something similar to pull out your name key ( objectForKey:#"name")
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"Info.plist"];
plist = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain];
NSString* version = [plist objectForKey:#"CFBundleVersion"];
Here's a StackOverflow question on working with data in plists. The answers get quite detailed.
Parse Plist (NSString) into NSDictionary