How to manage UITableView + Dynamic Custom Cell(UIBUtton + UITextField + UIBUtton) Insertion? - ios4

I am having problem in managing UITableView. I 'm posting a screenshot here to briefly explain the problem. Image 1 shows the default View when First Time view Appears. When I tap on yellow button(Yellow Button is in a custom table section header view) I open an UIAlertView with table in it like shown in the image 2. Then selecting any option I insert a custom cell with a button,textfield and another button. I have a mutable Array for each section so when I select an option I add that string into the corresponding section array and reloadtable.See image 3. Now when I enter values in UITextfields the values replaced by another cells. See the two images below for understanding the problem. image 4. Also when I delete a cell and insert a new the textfield is preloaded with previous value.
And here is the .m file implementation code for analyze the problem
#import "contactsViewController.h"
#import "textFieldCell.h"
#import "SBTableAlert.h"
#import "PhoneFieldCell.h"
#import "DHValidation.h"
#define kTextFieldTag 222
#define kTitleButtonTag 111
#define MAX_LENGTH 20
#define charecterLimit 13
#define PHONE_NUMBER #"0123456789+-"
#implementation contactsViewController
#synthesize currentTextField;
#synthesize choiceList;
#synthesize labelHeaders;
#synthesize selectedIndexPath;
#synthesize aTable;
#synthesize customText;
#synthesize currentSelectionType;
#synthesize phoneList;
#synthesize emailList;
#synthesize otherDetailsList;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
//Prepare array's for display in table header and in custom alert option table
[self prepareDataForTable];
[self initializeProperties];
//Set selected index to -1 by default
selectedIndex = -1;
}
//prepare array's for table
- (void) prepareDataForTable {
NSArray *temp = [[NSArray alloc] initWithObjects:#"work",#"home",#"mobile",#"custom",nil];
self.choiceList = temp;
[temp release];
NSArray *temp1 = [[NSArray alloc] initWithObjects:#"First Name",#"Last Name",nil];
self.labelHeaders = temp1;
[temp1 release];
}
- (void) initializeProperties {
//Initialize Mutable array's
NSMutableArray *temp = [[NSMutableArray alloc] initWithCapacity:0];
self.phoneList = temp;
[temp release];
NSMutableArray *temp1 = [[NSMutableArray alloc] initWithCapacity:0];
self.emailList = temp1;
[temp1 release];
NSMutableArray *temp2 = [[NSMutableArray alloc] initWithCapacity:0];
self.otherDetailsList = temp2;
[temp2 release];
}
#pragma mark -
- (IBAction) btnCancelTapped:(id) sender {
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction) btnDoneTapped:(id) sender {
[self.currentTextField resignFirstResponder];
//TODO: Fetch all the data from all the cells and notify the delegate.
NSMutableDictionary *allSectionsData = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
NSMutableDictionary *section1Dictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
NSMutableDictionary *phoneSectionDictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
NSMutableDictionary *emailSectionDictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
NSMutableDictionary *otherSectionDictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
//For Section 0
for (unsigned rowIndex = 0; rowIndex < 2; rowIndex++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:0];
UITableViewCell *cell = nil;
cell = (textFieldCell*)[aTable cellForRowAtIndexPath:indexPath];
UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];
//TextField validation
DHValidation *validation = [[DHValidation alloc] init];
NSString *str = [txtf.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *alertMessage = nil;
BOOL isvalid = NO;
if(![validation validateNotEmpty:str])
alertMessage = #"NameField should not be Empty";
else
isvalid = TRUE;
if(!isvalid){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:alertMessage delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
return ;
}
[validation release];
NSString *type = nil;
NSString *value = nil;
if(rowIndex == 0)
type = #"First Name";
else if(rowIndex == 1){
type = #"Last Name";
}
value = txtf.text;
if(!value){
//Do not insert that value in the dictinary
value = #"";
}else {
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,#"type",value,#"value",nil];
[section1Dictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
}
}
if([section1Dictionary count] > 0) {
[allSectionsData setObject:section1Dictionary forKey:#"PersonalDetailsSection"];
}
//For Section 1
for (unsigned rowIndex = 0; rowIndex < [phoneList count]; rowIndex++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:1];
UITableViewCell *cell = nil;
cell = (PhoneFieldCell*)[aTable cellForRowAtIndexPath:indexPath];
UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];
UIButton *btnTitle = (UIButton*)[cell viewWithTag:kTitleButtonTag];
NSString *type = nil;
NSString *value = nil;
type = [btnTitle currentTitle];
value = [txtf text];
if(!value || [[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:#""] ){
//Do not insert that value in the dictinary
continue;
}else {
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,#"type",value,#"value",nil];
[phoneSectionDictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
//[phoneSectionDictionary setObject:value forKey:type];
}
}
if([phoneSectionDictionary count] > 0) {
[allSectionsData setObject:phoneSectionDictionary forKey:#"PhoneSection"];
}
//For Section 2
for (unsigned rowIndex = 0; rowIndex < [emailList count]; rowIndex++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:2];
UITableViewCell *cell = nil;
cell = (PhoneFieldCell*)[aTable cellForRowAtIndexPath:indexPath];
UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];
UIButton *btnTitle = (UIButton*)[cell viewWithTag:kTitleButtonTag];
NSString *type = nil;
NSString *value = nil;
type = [btnTitle currentTitle];
value = [txtf text];
if(!value || [[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:#""] ){
//Do not insert that value in the dictinary
continue;
}else {
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,#"type",value,#"value",nil];
[emailSectionDictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
}
}
if([emailSectionDictionary count] > 0) {
[allSectionsData setObject:emailSectionDictionary forKey:#"EmailSection"];
}
//for Section 3
for (unsigned rowIndex = 0; rowIndex < [phoneList count]; rowIndex++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:3];
UITableViewCell *cell = nil;
cell = (PhoneFieldCell*)[aTable cellForRowAtIndexPath:indexPath];
UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];
UIButton *btnTitle = (UIButton*)[cell viewWithTag:kTitleButtonTag];
NSString *type = nil;
NSString *value = nil;
type = [btnTitle currentTitle];
value = [txtf text];
if(!value || [[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:#""] ){
//Do not insert that value in the dictinary
continue;
}else {
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,#"type",value,#"value",nil];
[otherSectionDictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
//[phoneSectionDictionary setObject:value forKey:type];
}
}
if([otherSectionDictionary count] > 0) {
[allSectionsData setObject:otherSectionDictionary forKey:#"OtherSection"];
}
}
#pragma mark -
#pragma mark UITableView Data Source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 4;
}
// Returns the number of rows in a given section.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger count = 0;
switch (section) {
case 0:
count = 2;
break;
case 1://Phone
count = [phoneList count];
break;
case 2://Email
count = [emailList count];
break;
case 3://Other
count = [otherDetailsList count];
break;
default:
count = 0;
break;
}
return count;
}
// Returns the cell for a given indexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"textFieldCustomCell";
static NSString *PhoneFieldCustomCellIdentifier = #"PhoneFieldCustomCell";
static NSString *EmailFieldCustomCellIdentifier = #"EmailFieldCustomCell";
static NSString *OtherDetailsCustomCellIdentifier = #"OtherDetailsCustomCell";
UITableViewCell *cell = nil;
switch (indexPath.section) {
case 0:{
cell = (textFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"textFieldCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[textFieldCell class]]){
cell = (textFieldCell *) currentObject;
break;
}
}
}
}
break;
case 1:{
cell = (PhoneFieldCell *)[tableView dequeueReusableCellWithIdentifier:PhoneFieldCustomCellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"PhoneFieldCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[PhoneFieldCell class]]){
cell = (PhoneFieldCell *) currentObject;
((PhoneFieldCell *)cell).enterText.delegate = self;
((PhoneFieldCell *)cell).enterText.text = nil;
break;
}
}
}
}
break;
case 2:{
cell = (EmailFieldCell *)[tableView dequeueReusableCellWithIdentifier:EmailFieldCustomCellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"EmailFieldCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[EmailFieldCell class]]){
cell = (EmailFieldCell *) currentObject;
((EmailFieldCell *)cell).enterText.delegate = self;
((EmailFieldCell *)cell).enterText.text = nil;
break;
}
}
}
}
break;
case 3:{
cell = (OtherDetailsCell *)[tableView dequeueReusableCellWithIdentifier:OtherDetailsCustomCellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"OtherDetailsCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[OtherDetailsCell class]]){
cell = (OtherDetailsCell *) currentObject;
((OtherDetailsCell *)cell).enterText.delegate = self;
((OtherDetailsCell *)cell).enterText.text = nil;
break;
}
}
}
}
break;
default:
break;
}
//Setup cell data
switch (indexPath.section) {
case 0:{
((textFieldCell*)cell).aTextField.delegate = self;
if(indexPath.row == 0){
((textFieldCell*)cell).aTextField.placeholder = #"Enter First Name";
}
if(indexPath.row == 1){
((textFieldCell*)cell).aTextField.placeholder = #"Enter Last Name";
}
((textFieldCell*)cell).aLabel.text = [self.labelHeaders objectAtIndex:indexPath.row];
}
break;
case 1:{
NSString *str = [phoneList objectAtIndex:indexPath.row];
[((PhoneFieldCell *)cell).changeBtn setTitle:str forState:UIControlStateNormal];
[((PhoneFieldCell *)cell).changeBtn addTarget:self action:#selector(changeButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
((PhoneFieldCell *)cell).btnDeleteCell.tag = indexPath.row;
[((PhoneFieldCell *)cell).btnDeleteCell addTarget:self action:#selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
break;
case 2:{
NSString *str = [emailList objectAtIndex:indexPath.row];
[((EmailFieldCell *)cell).changeBtn setTitle:str forState:UIControlStateNormal];
[((EmailFieldCell *)cell).changeBtn addTarget:self action:#selector(changeButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
((EmailFieldCell *)cell).btnDeleteCell.tag = indexPath.row;
[((EmailFieldCell *)cell).btnDeleteCell addTarget:self action:#selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
break;
case 3:{
NSString *str = [otherDetailsList objectAtIndex:indexPath.row];
[((OtherDetailsCell *)cell).changeBtn setTitle:str forState:UIControlStateNormal];
[((OtherDetailsCell *)cell).changeBtn addTarget:self action:#selector(changeButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
((OtherDetailsCell *)cell).btnDeleteCell.tag = indexPath.row;
[((OtherDetailsCell *)cell).btnDeleteCell addTarget:self action:#selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
break;
default:
break;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 30;
}
- (UIView*) tableView: (UITableView*) tableView viewForHeaderInSection: (NSInteger) section {
if (section == 0) {
return nil;
}
return [self headerViewForSection:section];
}
// Handle row selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
- (UIView*) headerViewForSection:(NSInteger)section {
CGRect lblTitleFrame = CGRectMake(15, 0, 200, 20);
CGRect btnFrame = CGRectMake(280.0, 0.0, 30.0, 30.0);
CGRect headerViewFrame = CGRectMake(0,0, 40, 30);
NSString *lblTitleText = nil;
switch (section) {
case 1://phone
lblTitleText = #"Phone";
break;
case 2://email
lblTitleText = #"Email";
break;
case 3://other details
lblTitleText = #"Other";
break;
default:
break;
}
//Create a header view with a label and a button
UIView *headerView = [[[UIView alloc] initWithFrame:headerViewFrame] autorelease];
UILabel *titleForTable = [[UILabel alloc]initWithFrame:lblTitleFrame];
titleForTable.text = lblTitleText;
titleForTable.backgroundColor = [UIColor clearColor];
titleForTable.textColor = [UIColor whiteColor];
titleForTable.shadowColor = [UIColor whiteColor];
[headerView addSubview:titleForTable];
[titleForTable release];
UIButton *phoneButton = [[UIButton alloc] initWithFrame:btnFrame];
phoneButton.alpha = 0.7;
phoneButton.tag = section;
[phoneButton setImage:[UIImage imageNamed:#"Yellow.png"] forState: UIControlStateNormal];
[phoneButton addTarget: self action: #selector(headerTapped:) forControlEvents: UIControlEventTouchUpInside];
[headerView addSubview: phoneButton];
[phoneButton release];
return headerView;
}
#pragma mark -
#pragma mark UITextField Delegate
- (void)textFieldDidBeginEditing:(UITextField *)textField {
self.currentTextField = textField;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
//textfield charecters range
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length >= MAX_LENGTH && range.length == 0){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"You reached maximum limit - 20"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
return NO; // return NO to not change text
}
else {
return YES;
}
}
#pragma mark -
- (void)deleteButtonTapped:(id)sender{
if([self.currentTextField isFirstResponder]) {
[self.currentTextField resignFirstResponder];
}
NSLog(#"Button Pressed");
UIButton *btnDelete = (UIButton*)sender;
id cell = [[btnDelete superview] superview];
if([cell isKindOfClass:[PhoneFieldCell class]]) {
cell = (PhoneFieldCell*)cell;
}
if([cell isKindOfClass:[EmailFieldCell class]]) {
cell = (EmailFieldCell*)cell;
}
if([cell isKindOfClass:[OtherDetailsCell class]]) {
cell = (OtherDetailsCell*)cell;
}
NSIndexPath *indexPath = [aTable indexPathForCell:cell];
NSLog(#"Section is %d and row is %d",indexPath.section,indexPath.row);
switch (indexPath.section) {
case 1:
[self.phoneList removeObjectAtIndex:[btnDelete tag]];
[aTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
break;
case 2:
[self.emailList removeObjectAtIndex:[btnDelete tag]];
[aTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
break;
case 3:
[self.otherDetailsList removeObjectAtIndex:[btnDelete tag]];
[aTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
break;
default:
break;
}
[aTable reloadData];
}
- (void)changeButtonTapped:(id)sender{
if([self.currentTextField isFirstResponder]) {
[self.currentTextField resignFirstResponder];
}
UIButton *btnDelete = (UIButton*)sender;
id cell = (PhoneFieldCell*)[[btnDelete superview] superview];
if([cell isKindOfClass:[PhoneFieldCell class]]) {
cell = (PhoneFieldCell*)cell;
}
if([cell isKindOfClass:[EmailFieldCell class]]) {
cell = (EmailFieldCell*)cell;
}
if([cell isKindOfClass:[OtherDetailsCell class]]) {
cell = (OtherDetailsCell*)cell;
}
self.selectedIndexPath = [aTable indexPathForCell:cell];
shouldModify = YES;
NSLog(#"Section is %d and row is %d",self.selectedIndexPath.section,self.selectedIndexPath.row);
SBTableAlert *alert = nil;
alert = [[[SBTableAlert alloc] initWithTitle:#"Options" cancelButtonTitle:#"Cancel" messageFormat:#"Select your option!"] autorelease];
[alert setType:SBTableAlertTypeSingleSelect];
[alert.view addButtonWithTitle:#"OK"];
[alert setDelegate:self];
[alert setDataSource:self];
[alert show];
}
- (void)headerTapped:(id)sender {
if([self.currentTextField isFirstResponder]) {
[self.currentTextField resignFirstResponder];
}
UIButton *tappedButton = (UIButton*)sender;
//set current selection according to section
switch ([tappedButton tag]) {
case 1://Phone
self.currentSelectionType = SELECTIONTYPE_PHONE;
break;
case 2://Email
self.currentSelectionType = SELECTIONTYPE_EMAIL;
break;
case 3://Other details
self.currentSelectionType = SELECTIONTYPE_OTHER;
break;
default:
break;
}
SBTableAlert *alert;
alert = [[[SBTableAlert alloc] initWithTitle:#"Options" cancelButtonTitle:#"Cancel" messageFormat:#"Select your option!"] autorelease];
[alert setType:SBTableAlertTypeSingleSelect];
[alert.view addButtonWithTitle:#"OK"];
[alert setDelegate:self];
[alert setDataSource:self];
[alert show];
}
#pragma mark - SBTableAlertDataSource
- (UITableViewCell *)tableAlert:(SBTableAlert *)tableAlert cellForRow:(NSInteger)row {
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil] autorelease];
[cell.textLabel setText:[self.choiceList objectAtIndex:row]];
if(row == selectedIndex)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else {
cell.accessoryType == UITableViewCellAccessoryNone;
}
return cell;
}
- (NSInteger)numberOfRowsInTableAlert:(SBTableAlert *)tableAlert {
if (tableAlert.type == SBTableAlertTypeSingleSelect)
return [self.choiceList count];
else
return 4;
}
#pragma mark - SBTableAlertDelegate
- (void)tableAlert:(SBTableAlert *)tableAlert didSelectRow:(NSInteger)row {
if (tableAlert.type == SBTableAlertTypeMultipleSelct) {
UITableViewCell *cell = [tableAlert.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0]];
if (cell.accessoryType == UITableViewCellAccessoryNone)
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
else
[cell setAccessoryType:UITableViewCellAccessoryNone];
[tableAlert.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] animated:YES];
}
else if (tableAlert.type == SBTableAlertTypeSingleSelect) {
selectedIndex = row;
[tableAlert.tableView reloadData];
[tableAlert.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] animated:YES];
}
}
- (void)tableAlert:(SBTableAlert *)tableAlert didDismissWithButtonIndex:(NSInteger)buttonIndex {
if(buttonIndex == 1){
if(selectedIndex == -1){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Select at least one choice" message:nil
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
}
else if(cellSelected == FALSE){
if(selectedIndex == 3){
UIAlertView *customAlert = [[UIAlertView alloc] initWithTitle:#"Enter Custom Message" message:#"\n\n"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok",nil];
customAlert.tag = 99;
CGAffineTransform myTransForm = CGAffineTransformMakeTranslation(0,0);
UITextField *temp = [[UITextField alloc] initWithFrame:CGRectMake(15, 50, 255, 30)];
self.customText = temp;
[temp release];
self.customText.backgroundColor = [UIColor whiteColor];
self.customText.placeholder = #"Enter Custom Text";
self.customText.clearButtonMode = UITextFieldViewModeWhileEditing;
self.customText.layer.cornerRadius = 5;
[customAlert addSubview:self.customText];
[customAlert setTransform:myTransForm];
[customAlert show];
[customAlert release];
}else {
UITableViewCell *cell = [tableAlert.tableView cellForRowAtIndexPath:[ NSIndexPath indexPathForRow:selectedIndex inSection:0]];
NSString *val = cell.textLabel.text;
if(!shouldModify) {
switch (self.currentSelectionType) {
case SELECTIONTYPE_PHONE:
[phoneList addObject:val];
break;
case SELECTIONTYPE_EMAIL:
[emailList addObject:val];
break;
case SELECTIONTYPE_OTHER:
[otherDetailsList addObject:val];
break;
default:
break;
}
}
else {
switch (self.selectedIndexPath.section) {
case 1:
[phoneList replaceObjectAtIndex:self.selectedIndexPath.row withObject:val];
break;
case 2:
[emailList replaceObjectAtIndex:self.selectedIndexPath.row withObject:val];
break;
case 3:
[otherDetailsList replaceObjectAtIndex:self.selectedIndexPath.row withObject:val];
break;
default:
break;
}
shouldModify = NO;
}
}
}
if(self.currentSelectionType != SELECTIONTYPE_UNKNOWN || self.selectedIndexPath.section > 0)
[aTable reloadData];
selectedIndex = -1;
[tableAlert release];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(alertView.tag == 99 && buttonIndex == 1){
NSString *val = [self.customText text];
if(!val || [[val stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:#""]){
//show error alert here and return from here
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Please fill a value for custom text"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[errorAlert show];
[errorAlert release];
return;
}
switch (self.currentSelectionType) {
case SELECTIONTYPE_PHONE:
[phoneList addObject:val];
[aTable reloadData];
break;
case SELECTIONTYPE_EMAIL:
[emailList addObject:val];
[aTable reloadData];
break;
case SELECTIONTYPE_OTHER:
[otherDetailsList addObject:val];
[aTable reloadData];
break;
default:
break;
}
}
}
#pragma mark -
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
self.currentTextField = nil;
self.choiceList = nil;
self.labelHeaders = nil;
self.selectedIndexPath = nil;
self.aTable = nil;
self.customText = nil;
self.phoneList = nil;
self.emailList = nil;
self.otherDetailsList = nil;
self.customText = nil;
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[phoneList release];
[emailList release];
[otherDetailsList release];
[customText release];
[customText release];
[aTable release];
[selectedIndexPath release];
[choiceList release];
[labelHeaders release];
[currentTextField release];
[super dealloc];
}
#end

here is your answer http://www.icodeblog.com/2011/01/04/elctextfieldcell-a-useful-tableviewcell-for-forms/
u can also manually do some customization according to your app need
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView reloadData];
}

Related

CoreDataTableViewController does not reload on return from segue

I have several CoreDataTableViewControllers that utilize the helper class from Paul Hegarty's course. Everyone of them works except this one, and I cannot see a difference.
When the table first comes up, it is correctly populated and the segue executes properly when a cell is selected. However when I hit the back button, the table displays (null), (null) everywhere.
I have tried every variant of calling [self useDocument] that I can think of, still to no avail. Any thoughts? Thanks in advance.
//
// TeamTableViewController.m
//
#import "TeamTableViewController.h"
#import "iTrackAppDelegate.h"
#import "CoreDataTableViewController.h"
#import "SchoolRecords.h"
#import "ScheduleViewController.h"
#interface TeamTableViewController ()
#property NSInteger toggle;
#end
#implementation TeamTableViewController
#synthesize iTrackContext = _iTrackContext;
#synthesize schoolSelected = _schoolSelected;
-(void) setSchoolSelected:(SchoolRecords *)schoolSelected
{
_schoolSelected = schoolSelected;
}
-(void) setITrackContext:(NSManagedObjectContext *)iTrackContext
{
if(_iTrackContext != iTrackContext){
if (!iTrackContext) {
MyCoreDataHandler* cdh =
[(iTrackAppDelegate *) [[UIApplication sharedApplication] delegate] cdh];
_iTrackContext = cdh.context;
} else {
_iTrackContext = iTrackContext;
}
}
[self useDocument];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)setupFetchedResultsController // attaches an NSFetchRequest to this UITableViewController
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"SchoolRecords"];
// no predicate because we want ALL the Athletes
request.sortDescriptors = [NSArray arrayWithObjects:
[NSSortDescriptor sortDescriptorWithKey:#"schoolName" ascending:YES],
nil];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.iTrackContext
sectionNameKeyPath:nil
cacheName:nil];
__block NSInteger myCount;
int64_t delayInSeconds = 5.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.iTrackContext performBlock:^(void){NSError* requestError = nil;
myCount = [self.iTrackContext countForFetchRequest:request error:&requestError];
NSLog(#"In %# and count of iTrackContext = %lu", NSStringFromClass([self class]),(unsigned long)myCount);
}];
if (!myCount || myCount == 0) {
[self displayAlertBoxWithTitle:#"No Teams" message:#"Have you added athletes yet? \nPlease go to Add Athletes" cancelButton:#"Okay"];
}
});
}
- (void)useDocument
{
if (self.iTrackContext) {
[self setupFetchedResultsController];
} else {
NSString* errorText = #"A problem arose opening the search results database of Athletes.";
[self displayAlertBoxWithTitle:#"File Error" message:errorText cancelButton:#"Okay"];
}
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (!self.iTrackContext) {
MyCoreDataHandler* cdh =
[(iTrackAppDelegate *) [[UIApplication sharedApplication] delegate] cdh];
[self setITrackContext:cdh.context];
} else {
NSLog(#"In %# of %#. Getting ready to call useDocument",NSStringFromSelector(_cmd), self.class);
[self useDocument];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// If divide into sections use line below otherwise return 1.
// return [[self.fetchedResultsController sections] count];
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Do not really need this with only one section, but makes code usable if add sections later.
return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"teamInformation";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
SchoolRecords *schoolResults = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString* titleText = schoolResults.schoolName;
cell.textLabel.text = titleText;
cell.detailTextLabel.text = [NSMutableString stringWithFormat:#"%#, %#", schoolResults.schoolCity, schoolResults.schoolState];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
# pragma navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
[self setSchoolSelected:[self.fetchedResultsController objectAtIndexPath:indexPath]];
// be somewhat generic here (slightly advanced usage)
// we'll segue to ANY view controller that has a photographer #property
if ([segue.identifier isEqualToString:#"scheduleDetailSegue"]) {
// use performSelector:withObject: to send without compiler checking
// (which is acceptable here because we used introspection to be sure this is okay)
NSLog(#"Preparing to passing school with schoolID = %#", self.schoolSelected.schoolID);
[segue.destinationViewController convenienceMethodForSettingSchool:self.schoolSelected];
}
}
- (void) displayAlertBoxWithTitle:(NSString*)title message:(NSString*) myMessage cancelButton:(NSString*) cancelText
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:myMessage
delegate:nil
cancelButtonTitle:cancelText
otherButtonTitles:nil];
[alert show];
}
#end
Well, I am not certain what the problem was. I ended up deleting the "offending" TableViewControllers in StoryBoard and recreated them. That did the trick. In retrospect, I wonder if I did not specify the wrong type of segue from my tabViewController. But I deleted it before I thought of that possibility.

Selecting TableView cell returns incorrect object

I followed a tutorial I found online to create a tableview with sections and an index from an array of custom objects. This code works with the exception that when I select a row in the table I the index path for that section and not for the entire array. I can see why it doesn't work but I can't figure out how to address the fix, this is my cell for tableview code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"NameCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
int displayOrder = [defaults integerForKey:#"displayOrder"];
int sortOrder = [defaults integerForKey:#"sortOrder"];
NSString *alphabet = [listIndex objectAtIndex:[indexPath section]];
NSPredicate *sectionPredicate = [[NSPredicate alloc] init];
if (sortOrder == 1) {
//NSLog(#"fName is predicate at cell level");
sectionPredicate = [NSPredicate predicateWithFormat:#"fName beginswith[c] %#", alphabet];
} else {
//NSLog(#"lName is predicate at cell level");
sectionPredicate = [NSPredicate predicateWithFormat:#"lName beginswith[c] %#", alphabet];
}
NSArray *sectionContacts = [filteredList filteredArrayUsingPredicate:sectionPredicate];
if (isSearching) {
current = [filteredList objectAtIndex:indexPath.row];
} else{
current = [sectionContacts objectAtIndex:indexPath.row];
}
if (displayOrder == 1) {
NSString *fullName = [NSString stringWithFormat:#"%# %#",[current valueForKey:#"fName"],[current valueForKey:#"lName"]];
[cell.textLabel setText:fullName];
//NSLog(#"FirstNameFirst");
} else {
NSString *fullName = [NSString stringWithFormat:#"%# %#",[current valueForKey:#"lName"],[current valueForKey:#"fName"]];
[cell.textLabel setText:fullName];
//NSLog(#"LastNameFirst");
}
[cell.detailTextLabel setText:[current valueForKey:#"extension"]];
return cell; }
THen I call the segue with this code.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showContact"]) {
DetailViewController *dvc = [segue destinationViewController];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
NSDictionary *c = [filteredList objectAtIndex:path.row];
[dvc setCurrentContact:c];
[searchBar resignFirstResponder];
} }
The problem is that the objectAtIndex:path.row returns the index for that section but it isn't modified for the entire array, so if a name in the "B" section that is at index 4 of that section is tapped it returns the object at index 4 of the primary array. I have been scratching my head to figure out how to get the index for the full array and not for the one that is only local to that section.
I'll buy you a 6 pack of your favorite beverage if you can help!
Thanks!
You do it the same way that they do it in the first function, so change your prepareForSegue to this:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showContact"]) {
DetailViewController *dvc = [segue destinationViewController];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
NSDictionary *c;
NSString *alphabet = [listIndex objectAtIndex:[path section]];
NSPredicate *sectionPredicate = [[NSPredicate alloc] init];
if (sortOrder == 1) {
sectionPredicate = [NSPredicate predicateWithFormat:#"fName beginswith[c] %#", alphabet];
} else {
sectionPredicate = [NSPredicate predicateWithFormat:#"lName beginswith[c] %#", alphabet];
}
NSArray *sectionContacts = [filteredList filteredArrayUsingPredicate:sectionPredicate];
if (isSearching) {
c = [filteredList objectAtIndex:path.row];
} else{
c = [sectionContacts objectAtIndex:path.row];
}
[dvc setCurrentContact:c];
[searchBar resignFirstResponder];
}
}
Note that it would probably be best to pull the common code out and make a separate function instead of using it twice like this.

Background-queue changes to parent NSManagedObjectContext in UIManagedDocument cause duplicate in NSFetchedresultsController on merge

Ok guys. This one is driving me up the wall. I have
UIManagedDocument and its 2 MOContexts (regular and parent.)
A UITableViewController (subclassed to CoreDataTableViewController by Paul Hegarty) that runs off of an
NSFetchedResultsController
A background GCD Queue for syncing with the server that the parent cue accesses
I've tried this so many different ways and I run into problems each time.
When I add a new "animal" entity, it is no problem and immediately shows up on the table. But when I upload it to the server (on the upload queue) and changed its "status" (with the parent context) so that it should be in the uploaded section, it appears there but doesn't disappear from the un-uploaded section.
I END UP WITH TWINS I DIDN'T WANT! or it doesn't even make the correct one sometimes and just keeps the wrong one.
***BUT, the extra one will disappear when the app is shut down and reloaded. So it's just in memory somewhere. I can verify in the store that everything is correct. But the NSFetchedResultsController isn't firing the controllerDidChange... stuff.
Here is the superclass of my view controller
CoreDataTableViewController.m
#pragma mark - Fetching
- (void)performFetch
{
self.debug = 1;
if (self.fetchedResultsController) {
if (self.fetchedResultsController.fetchRequest.predicate) {
if (self.debug) NSLog(#"[%# %#] fetching %# with predicate: %#", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName, self.fetchedResultsController.fetchRequest.predicate);
} else {
if (self.debug) NSLog(#"[%# %#] fetching all %# (i.e., no predicate)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName);
}
NSError *error;
[self.fetchedResultsController performFetch:&error];
if (error) NSLog(#"[%# %#] %# (%#)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), [error localizedDescription], [error localizedFailureReason]);
} else {
if (self.debug) NSLog(#"[%# %#] no NSFetchedResultsController (yet?)", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
}
[self.tableView reloadData];
}
- (void)setFetchedResultsController:(NSFetchedResultsController *)newfrc
{
NSFetchedResultsController *oldfrc = _fetchedResultsController;
if (newfrc != oldfrc) {
_fetchedResultsController = newfrc;
newfrc.delegate = self;
if ((!self.title || [self.title isEqualToString:oldfrc.fetchRequest.entity.name]) && (!self.navigationController || !self.navigationItem.title)) {
self.title = newfrc.fetchRequest.entity.name;
}
if (newfrc) {
if (self.debug) NSLog(#"[%# %#] %#", NSStringFromClass([self class]), NSStringFromSelector(_cmd), oldfrc ? #"updated" : #"set");
[self performFetch];
} else {
if (self.debug) NSLog(#"[%# %#] reset to nil", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
[self.tableView reloadData];
}
}
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (self.debug) NSLog(#"fetchedResultsController returns %d sections", [[self.fetchedResultsController sections] count]);
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [[[self.fetchedResultsController sections] objectAtIndex:section] name];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex: (NSInteger)index
{
return [self.fetchedResultsController sectionForSectionIndexTitle:title atIndex:index];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return [self.fetchedResultsController sectionIndexTitles];
}
#pragma mark - NSFetchedResultsControllerDelegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
{
[self.tableView beginUpdates];
self.beganUpdates = YES;
}
}
- (void)controller:(NSFetchedResultsController *)controller
didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex
forChangeType:(NSFetchedResultsChangeType)type
{
if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
}
- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
if(self.debug) NSLog(#"controller didChangeObject: %#", anObject);
if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
{
NSLog(#"#########Controller did change type: %d", type);
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
if (self.beganUpdates) [self.tableView endUpdates];
if (self.debug) NSLog(#"controller Did Change Content");
}
- (void)endSuspensionOfUpdatesDueToContextChanges
{
_suspendAutomaticTrackingOfChangesInManagedObjectContext = NO;
}
- (void)setSuspendAutomaticTrackingOfChangesInManagedObjectContext:(BOOL)suspend
{
if (suspend) {
_suspendAutomaticTrackingOfChangesInManagedObjectContext = YES;
} else {
[self performSelector:#selector(endSuspensionOfUpdatesDueToContextChanges) withObject:0 afterDelay:0];
}
}
#end
And here's my specific view controller I subclassed from it:
- (NSArray *)sectionHeaderTitles
{
if (_sectionHeaderTitles == nil) _sectionHeaderTitles = [NSArray arrayWithObjects:#"Not Yet Uploaded", #"Uploaded But Not Featured", #"Previously Featured", nil];
return _sectionHeaderTitles;
}
- (NSDictionary *)selectedEntry
{
if (_selectedEntry == nil) _selectedEntry = [[NSDictionary alloc] init];
return _selectedEntry;
}
- (void)setupFetchedResultsController
{
[self.photoDatabase.managedObjectContext setStalenessInterval:0.0];
[self.photoDatabase.managedObjectContext.parentContext setStalenessInterval:0.0];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Animal"];
request.sortDescriptors = [NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:#"status" ascending:YES], [NSSortDescriptor sortDescriptorWithKey:#"unique" ascending:NO], nil];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.photoDatabase.managedObjectContext sectionNameKeyPath:#"status" cacheName:nil];
NSError *error;
BOOL success = [self.fetchedResultsController performFetch:&error];
if (!success) NSLog(#"error: %#", error);
else [self.tableView reloadData];
self.fetchedResultsController.delegate = self;
}
- (void)useDocument
{
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.photoDatabase.fileURL path]]) {
[self.photoDatabase saveToURL:self.photoDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self setupFetchedResultsController];
}];
} else if (self.photoDatabase.documentState == UIDocumentStateClosed) {
[self.photoDatabase openWithCompletionHandler:^(BOOL success) {
[self setupFetchedResultsController];
}];
} else if (self.photoDatabase.documentState == UIDocumentStateNormal) {
[self setupFetchedResultsController];
}
}
- (void)setPhotoDatabase:(WLManagedDocument *)photoDatabase
{
if (_photoDatabase != photoDatabase) {
_photoDatabase = photoDatabase;
[self useDocument];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont fontWithName:#"AmericanTypewriter" size:20];
label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
label.textAlignment = UITextAlignmentCenter;
label.textColor = [UIColor whiteColor];
self.navigationItem.titleView = label;
label.text = self.navigationItem.title;
[label sizeToFit];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Get CoreData database made if necessary
if (!self.photoDatabase) {
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:#"Default Photo Database"];
self.photoDatabase = [[WLManagedDocument alloc] initWithFileURL:url];
NSLog(#"No existing photoDatabase so a new one was created from default photo database file.");
}
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"DarkWoodBackGround.png"]];
}
- (void)syncWithServer
{
// This is done on the syncQ
// Start the activity indicator on the nav bar
dispatch_async(dispatch_get_main_queue(), ^{
[self.spinner startAnimating];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.spinner];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(managedObjectContextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:self.photoDatabase.managedObjectContext.parentContext];
});
// Find new animals (status == 0)
NSFetchRequest *newAnimalsRequest = [NSFetchRequest fetchRequestWithEntityName:#"Animal"];
newAnimalsRequest.predicate = [NSPredicate predicateWithFormat:#"status == 0"];
NSError *error;
NSArray *newAnimalsArray = [self.photoDatabase.managedObjectContext.parentContext executeFetchRequest:newAnimalsRequest error:&error];
if ([newAnimalsArray count]) NSLog(#"There are %d animals that need to be uploaded.", [newAnimalsArray count]);
if (error) NSLog(#"fetchError: %#", error);
// Get the existing animals from the server
NSArray *parsedDownloadedAnimalsByPhoto = [self downloadedAllAnimalsFromWeb];
// In the parent context, insert downloaded animals into core data
for (NSDictionary *downloadedPhoto in parsedDownloadedAnimalsByPhoto) {
[Photo photoWithWebDataInfo:downloadedPhoto inManagedObjectContext:self.photoDatabase.managedObjectContext.parentContext];
// table will automatically update due to NSFetchedResultsController's observing of the NSMOC
}
// Upload the new animals if there are any
if ([newAnimalsArray count] > 0) {
NSLog(#"There are %d animals that need to be uploaded.", [newAnimalsArray count]);
for (Animal *animal in newAnimalsArray) {
// uploadAnimal returns a number that lets us know if it was accepted by the server
NSNumber *unique = [self uploadAnimal:animal];
if ([unique intValue] != 0) {
animal.unique = unique;
// uploadThePhotosOf returns a success BOOL if all 3 uploaded successfully
if ([self uploadThePhotosOf:animal]){
[self.photoDatabase.managedObjectContext performBlock:^{
animal.status = [NSNumber numberWithInt:1];
}];
}
}
}
}
[self.photoDatabase.managedObjectContext.parentContext save:&error];
if (error) NSLog(#"Saving parent context error: %#", error);
[self performUpdate];
// Turn the activity indicator off and replace the sync button
dispatch_async(dispatch_get_main_queue(), ^{
// Save the context
[self.photoDatabase saveToURL:self.photoDatabase.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) {
if (success)
{
NSLog(#"Document was saved");
[self.photoDatabase.managedObjectContext processPendingChanges];
} else {
NSLog(#"Document was not saved");
}
}];
[self.spinner stopAnimating];
self.navigationItem.leftBarButtonItem = self.syncButton;
});
// Here it skips to the notification I got from saving the context so I can MERGE them
}
- (NSNumber *)uploadAnimal:(Animal *)animal
{
NSURL *uploadURL = [NSURL URLWithString:#"index.php" relativeToURL:self.remoteBaseURL];
NSString *jsonStringFromAnimalMetaDictionary = [animal.metaDictionary JSONRepresentation];
NSLog(#"JSONRepresentation of %#: %#", animal.namestring, jsonStringFromAnimalMetaDictionary);
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:uploadURL];
[request setPostValue:jsonStringFromAnimalMetaDictionary forKey:#"newmeta"];
[request startSynchronous];
NSError *error = [request error];
NSString *response;
if (!error) {
response = [request responseString];
NSNumber *animalUnique = [(NSArray *)[response JSONValue]objectAtIndex:0];
return animalUnique;
} else {
response = [error description];
NSLog(#"%# got an error: %#", animal.namestring, response);
return [NSNumber numberWithInt:0];
}
}
- (BOOL)uploadThePhotosOf:(Animal *)animal
{
NSURL *uploadURL = [NSURL URLWithString:#"index.php" relativeToURL:self.remoteBaseURL];
int index = [animal.photos count];
for (Photo *photo in animal.photos) {
// Name the jpeg file
NSTimeInterval timeInterval = [NSDate timeIntervalSinceReferenceDate];
NSString *imageServerPath = [NSString stringWithFormat:#"%lf-Photo.jpeg",timeInterval];
// Update the imageServerPath
photo.imageURL = imageServerPath;
NSData *photoData = [[NSData alloc] initWithData:photo.image];
NSString *photoMeta = [photo.metaDictionary JSONRepresentation];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:uploadURL];
[request addPostValue:photoMeta forKey:#"newphoto"];
[request addData:photoData withFileName:imageServerPath andContentType:#"image/jpeg" forKey:#"filename"];
[request setUploadProgressDelegate:self.progressView];
[request startSynchronous];
NSLog(#"%# progress: %#", animal.namestring, self.progressView.progress);
NSString *responseString = [request responseString];
NSLog(#"uploadThePhotosOf:%# photo at placement: %d has responseString: %#", animal.namestring, [photo.placement intValue], responseString);
SBJsonParser *parser= [[SBJsonParser alloc] init];
NSError *error = nil;
id jsonObject = [parser objectWithString:responseString error:&error];
NSNumber *parsedPhotoUploadResponse = [(NSArray *)jsonObject objectAtIndex:0];
// A proper response is not 0
if ([parsedPhotoUploadResponse intValue] != 0) {
photo.imageid = parsedPhotoUploadResponse;
--index;
}
}
// If the index spun down to 0 then it was successful
int success = (index == 0) ? 1 : 0;
return success;
}
- (NSArray *)downloadedAllAnimalsFromWeb
{
NSURL *downloadURL = [NSURL URLWithString:#"index.php" relativeToURL:self.remoteBaseURL];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:downloadURL];
[request setPostValue:#"yes" forKey:#"all"];
request.tag = kGetHistoryRequest;
[request startSynchronous];
NSString *responseString = [request responseString];
NSLog(#"downloadedAllAnimalsFromWeb responseString: %#", responseString);
SBJsonParser *parser= [[SBJsonParser alloc] init];
NSError *error = nil;
id jsonObject = [parser objectWithString:responseString error:&error];
NSArray *parsedDownloadedResponseStringArray = [NSArray arrayWithArray:jsonObject];
return parsedDownloadedResponseStringArray;
}
- (void)performUpdate
{
NSManagedObjectContext * context = self.photoDatabase.managedObjectContext.parentContext;
NSSet * inserts = [context updatedObjects];
if ([inserts count])
{
NSError * error = nil;
NSLog(#"There were inserts");
if ([context obtainPermanentIDsForObjects:[inserts allObjects]
error:&error] == NO)
{
NSLog(#"BAM! %#", error);
}
}
[self.photoDatabase updateChangeCount:UIDocumentChangeDone];
}
- (void)managedObjectContextDidSave:(NSNotification *)notification
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.photoDatabase.managedObjectContext.parentContext];
NSLog(#"userInfo from the notification: %#", [notification userInfo]);
// Main thread context
NSManagedObjectContext *context = self.fetchedResultsController.managedObjectContext;
SEL selector = #selector(mergeChangesFromContextDidSaveNotification:);
[context performSelectorOnMainThread:selector withObject:notification waitUntilDone:YES];
NSLog(#"ContextDidSaveNotification was sent. MERGED");
}
#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"EntryCell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"EntryCell"];
}
// Configure the cell here...
Animal *animal = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = animal.namestring;
if (([animal.numberofanimals intValue] > 0) && animal.species) {
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#s", animal.species];
} else {
cell.detailTextLabel.text = animal.species;
}
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
Animal *animal = [self.fetchedResultsController objectAtIndexPath:indexPath];
// be somewhat generic here (slightly advanced usage)
// we'll segue to ANY view controller that has a photographer #property
if ([segue.identifier isEqualToString:#"newAnimal"]) {
NSLog(#"self.photodatabase");
[(NewMetaEntryViewController *)[segue.destinationViewController topViewController] setPhotoDatabaseContext:self.photoDatabase.managedObjectContext];
} else if ([segue.destinationViewController respondsToSelector:#selector(setAnimal:)]) {
// use performSelector:withObject: to send without compiler checking
// (which is acceptable here because we used introspection to be sure this is okay)
[segue.destinationViewController performSelector:#selector(setAnimal:) withObject:animal];
NSLog(#"animal: %# \r\n indexPath: %#", animal, indexPath);
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return nil;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSLog(#"header for section called for section: %d", section);
NSLog(#"fetchedResultsController sections: %#", self.fetchedResultsController.sections);
CGRect headerRect = CGRectMake(0, 0, tableView.bounds.size.width, 30);
UIView *header = [[UIView alloc] initWithFrame:headerRect];
UILabel *headerTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, tableView.bounds.size.width - 10, 20)];
if ([(Animal *)[[[[self.fetchedResultsController sections] objectAtIndex:section] objects] objectAtIndex:0] status] == [NSNumber numberWithInt:0]) {
headerTitleLabel.text = [self.sectionHeaderTitles objectAtIndex:0];
} else if ([(Animal *)[[[[self.fetchedResultsController sections] objectAtIndex:section] objects] objectAtIndex:0] status] == [NSNumber numberWithInt:1]) {
headerTitleLabel.text = [self.sectionHeaderTitles objectAtIndex:1];
} else {
headerTitleLabel.text = [self.sectionHeaderTitles objectAtIndex:2];
}
headerTitleLabel.textColor = [UIColor whiteColor];
headerTitleLabel.font = [UIFont fontWithName:#"AmericanTypewriter" size:20];
headerTitleLabel.backgroundColor = [UIColor clearColor];
headerTitleLabel.alpha = 0.8;
[header addSubview:headerTitleLabel];
return header;
}
Way too much code for anyone to want to wade through.
However, from a quick inspection, it looks like you are violating the MOC constraints. Specifically, you are accessing the parent context directly, and not from its own thread, either.
Typically, you would start a new thread, then create a MOC in that thread, make its parent be the MOC of the document. then do your stuff, and call save on the new MOC. It will then notify the parent, which should handle the updating.

Not able to retrieve data from database in ios

I want to save some data into sqlite database and the read it, there is no problem while saving the data but i am not able to retrieve data from database.
Here is the code that I'm using.
//>>>>>> to save in sqlite Database
-(void)saveData
{
NSString *strTxtFldValue = txtFldName.text;
sqlite3_stmt *statement;
const char *dbpath = [appDel.databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:#"INSERT INTO TESTTABLE (NAME) VALUES (\"%#\")",strTxtFldValue];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
NSLog(#"Data is added succesfully ");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Confirmation" message:#"Name is added successfully." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
} else {
NSLog(#"Failed to add data");
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}
//>>>>>> to read from database
//here the control comes till second NSLog and the "sqlite3_prepare_v2" statement doesn't get execute.
-(void)readData{
const char *dbpath = [appDel.databasePath UTF8String];
sqlite3_stmt *statement;
NSLog(#"^^^^^^^ 1");
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSLog(#"^^^^^^^ 2");
// NSString *querySQL = [NSString stringWithFormat:#"SELECT * FROM TESTTABLE"];
NSString *querySQL = [NSString stringWithFormat:#"SELECT NAME FROM TESTTABLE"];
const char *query_stmt = [querySQL UTF8String];
**if (sqlite3_prepare_v2(database,query_stmt, -1, &statement, NULL) == SQLITE_OK)**
{
NSLog(#"^^^^^^^ 3");
while(sqlite3_step(statement) == SQLITE_ROW)
{
NSLog(#"^^^^^^^ 4");
NSString *cName = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
NSLog(#"~~~~### cName = %#",cName);
Names *name = [[Names alloc] initWithName:cName];
[names addObject:name];
[name release];
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
}
}
Please provide the solution.
Thanks in advance
Create the database at runtime, and use the below logic,
to write the data in sqlite.
sqlite3 *pDb;
char *databaseName;
databaseName = #"TempDatabase.sql";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
//databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
databasePath =[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"TempDatabase.sql"];
//[self copyDatabaseIfNeeded];
if(sqlite3_open([databasePath UTF8String], &pDb) == SQLITE_OK)
{
const char *sqlStatement = "INSERT INTO tablename (name) VALUES(?)";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(pDb, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
sqlite3_bind_text( compiledStatement, 1, [strTxtFldValue UTF8String], -1, SQLITE_TRANSIENT);
}
if(sqlite3_step(compiledStatement) != SQLITE_DONE )
{
NSLog( #"~~~~~~~~~~~ 1 Error: %s", sqlite3_errmsg(pDb) );
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Name name is not added." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Confirmation" message:#"name is added successfully." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(pDb);
To read data from sqlite
sqlite3 *database;
const char *dbpath = [appDel.databasePath UTF8String];
sqlite3_stmt *statement;
NSMutableArray *names = [[NSMutableArray alloc]init];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
const char *sqlStatement = "select name from tablename";
if (sqlite3_prepare_v2(database, sqlStatement, -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *cName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,0)];
//NSLog(#"cName = %#",cName);
Names *name = [[Names alloc] initWithName:cName];
[names addObject:name];
[name release];
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
Try out this and vote me if it works fine for you.

How do you get an SQLITE database (Mydb.db) to load every time you start the iPhone App?

I have an app that access a static SQLITE database when running. A user or application is not allowed to alter or update this database. However, I need to add records or change field content to keep up with changing URLs etc. I use MesaSQLite to update the single table. But when I re-open the app in Xcode Simulator, none of the changes took effect. It's as if the app did not reload the updated database.
How can I get a reload to take place? Keep in mind that I'm still covered in shrink wrap because I'm so new to coding !!!
I'm not really sure of the SQL part. but I think that you will need to reload the table content after getting the update from the database. If you post some code, I can help you better. Here's how to reload the table:
[myTable reloadData];
And you will need to update the table with the new data in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
This is an IOS4.2 iPhone app. Here is the code for accessing and displaying the sort results of the database. The purpose is to use the database to sort delegates by event and state, then display the results. The displayed delegates are linked to a website. Again, the user and the app DO NOT alter the database, it's static. I use an SQLite editor to make changes and import them back into the databases' single table. I just need the table reloaded when this portion of the code runs.
I'll need to know what code and where to insert it for table reload.
Thanks for your help !!!!!
//
// delegateList.m
// foundingFathers
//
// Created by __ on 6/23/10.
// Copyright 2010 MyCompanyName. All rights reserved.
//
import "delegateList.h"
static sqlite3 *database = nil;
#implementation delegateList
#synthesize tableView;
-(void)viewDidLoad
{
nameArray = [[NSMutableArray alloc] init];
stateArray = [[NSMutableArray alloc] init];
yearsArray = [[NSMutableArray alloc] init];
contArray = [[NSMutableArray alloc] init];
indArray = [[NSMutableArray alloc] init];
confArray = [[NSMutableArray alloc] init];
constArray = [[NSMutableArray alloc] init];
urlArray = [[NSMutableArray alloc] init];
stateNameArray = [[NSMutableArray alloc] init];
eventNameArray = [[NSMutableArray alloc] init];
[self loadStateData];
[self loadEventData];
// Setup some globals
databaseName = #"mydb.db";
// Get the path to the documents directory and append the databaseName
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
// Execute the "checkAndCreateDatabase" function
[self checkAndCreateDatabase];
// Query the database for all delegates
[self loadDataWithState:#"" andEvent:0];
}
-(void)loadStateData
{
[stateNameArray addObject:#"All States"];
[stateNameArray addObject:#"Connecticut"];
[stateNameArray addObject:#"Delaware"];
[stateNameArray addObject:#"Georgia"];
[stateNameArray addObject:#"Maryland"];
[stateNameArray addObject:#"Massachusetts"];
[stateNameArray addObject:#"New Hampshire"];
[stateNameArray addObject:#"New Jersey"];
[stateNameArray addObject:#"New York"];
[stateNameArray addObject:#"North Carolina"];
[stateNameArray addObject:#"Pennsylvania"];
[stateNameArray addObject:#"Rhode Island"];
[stateNameArray addObject:#"South Carolina"];
[stateNameArray addObject:#"Virginia"];
}
-(void)loadEventData
{
[eventNameArray addObject:#"All Events"];
[eventNameArray addObject:#"Continental Association"];
[eventNameArray addObject:#"Declaration of Independence"];
[eventNameArray addObject:#"Confederation of States"];
[eventNameArray addObject:#"US Constitution"];
}
-(IBAction)nextPressed:(id)sender
{
[self.navigationController pushViewController:nondelegateList animated:YES];
}
-(IBAction)menuPressed:(id)sender
{
[self.navigationController popToViewController:mainmenu animated:YES];
}
/*
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
switch (interfaceOrientation) {
case UIInterfaceOrientationPortrait:
case UIInterfaceOrientationPortraitUpsideDown:
return NO;
break;
default:
return YES;
break;
}
}*/
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [nameArray count]+1;
}
-(UITableViewCell *)tableView:(UITableView *)tblView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
MyIdentifier = #"tblViewCell";
TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if(cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TableCellView" owner:self options:nil];
cell = tblCell;
}
UILabel* lbl;
if (indexPath.row == 0) //table Headers
{
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
lbl = (UILabel *)[cell viewWithTag:1];
[lbl setFont:[UIFont boldSystemFontOfSize:14]];
lbl.text = #"Name";
[lbl setTextAlignment:UITextAlignmentLeft];
lbl = (UILabel *)[cell viewWithTag:2];
[lbl setFont:[UIFont boldSystemFontOfSize:14]];
lbl.text = #"State";
[lbl setTextAlignment:UITextAlignmentLeft];
} else {
//[lbl setFont:[[lbl font] fontWithSize:9]];
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
lbl = (UILabel *)[cell viewWithTag:1];
[lbl setTextAlignment:UITextAlignmentLeft];
[lbl setFont:[UIFont systemFontOfSize:14]];
lbl.text = [nameArray objectAtIndex:indexPath.row-1];
lbl = (UILabel *)[cell viewWithTag:2];
[lbl setTextAlignment:UITextAlignmentLeft];
[lbl setFont:[UIFont systemFontOfSize:14]];
lbl.text = [stateArray objectAtIndex:indexPath.row-1];
}
return cell;
}
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
return;
}
NSURL* page = [NSURL URLWithString:[urlArray objectAtIndex:indexPath.row - 1] ];
NSURLRequest* pageRequest = [NSURLRequest requestWithURL:page];
[webTitle setTitle:[nameArray objectAtIndex:indexPath.row - 1]];
[web loadRequest:pageRequest];
[self.navigationController pushViewController:webView animated:YES];
}
-(void) checkAndCreateDatabase{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:databasePath];
if(success) return;
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
//[fileManager release];
}
-(void)loadDataWithState:(NSString*)stateSearch andEvent:(int)eventSearch
{
BOOL hasEvent = (BOOL)eventSearch;
BOOL hasState = !([stateSearch isEqualToString:#"All States"] || stateSearch.length <=0);
NSString* state = stateSearch;
NSString* event = nil;
switch (eventSearch) {
case 1:
event = #"continental";
break;
case 2:
event = #"declaration";
break;
case 3:
event = #"confederation";
break;
case 4:
event = #"constitution";
break;
default:
break;
}
// Open the database from the users filessytem
if(database || sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
NSString* sqlString = nil;
const char *sqlStatement;
if (hasEvent && hasState) {
sqlString = [[[[#"select * from founding_fathers where "stringByAppendingString:event] stringByAppendingString:#" like 'X%%' and State like '"] stringByAppendingString:state] stringByAppendingString:#"'"];
}
if (hasEvent && !hasState) {
sqlString = [[#"select * from founding_fathers where " stringByAppendingString:event] stringByAppendingString:#" like 'X%%'"];
}
if (!hasEvent && hasState) {
sqlString = [[#"select * from founding_fathers where state = '" stringByAppendingString:state] stringByAppendingString:#"'"];
}
if (!hasEvent && !hasState) {
sqlString= #"select * from founding_fathers";
}
unsigned int lengthOfMessage = [sqlString length];
char temp[lengthOfMessage + 1];
strcpy(temp, [sqlString cString]);
sqlStatement = temp;
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
[nameArray removeAllObjects];
[stateArray removeAllObjects];
[yearsArray removeAllObjects];
[contArray removeAllObjects];
[indArray removeAllObjects];
[confArray removeAllObjects];
[constArray removeAllObjects];
[urlArray removeAllObjects];
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString* dName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString* dState = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString* dYears = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSString* dCont = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 4)];
NSString* dInd = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 5)];
NSString* dConf = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 6)];
NSString* dConst = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 7)];
NSString* dUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 8)];
[nameArray addObject:dName];
[stateArray addObject:dState];
[yearsArray addObject:dYears];
[contArray addObject:dCont];
[indArray addObject:dInd];
[confArray addObject:dConf];
[constArray addObject:dConst];
[urlArray addObject:dUrl];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
}
-(void)viewDidUnload
{
sqlite3_close(database);
}
-(IBAction)stateSearch:(id)sender
{
pickerArray = stateNameArray;
[picker reloadAllComponents];
[picker setHidden:NO];
[doneButton setHidden:NO];
}
-(IBAction)eventSearch:(id)sender
{
pickerArray = eventNameArray;
[picker reloadAllComponents];
[picker setHidden:NO];
[doneButton setHidden:NO];
}
(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [pickerArray count];
}
(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [pickerArray objectAtIndex:row];
}
(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
}
(void) doneClicked:(id)sender
{
if (pickerArray == stateNameArray)
{
stateSearchChoice = [stateNameArray objectAtIndex:[picker selectedRowInComponent:0]];
[stateButton setTitle:stateSearchChoice];
}
if (pickerArray == eventNameArray) {
eventSearchChoice = [picker selectedRowInComponent:0];
[eventButton setTitle:[eventNameArray objectAtIndex:[picker selectedRowInComponent:0]]];
}
[picker setHidden:YES];
[doneButton setHidden:YES];
[self loadDataWithState:stateSearchChoice andEvent:eventSearchChoice];
[tableView reloadData];
}
#end

Resources