NSMutable array adding entries? - iphone

I am pretty new to objective-c and I am creating an app where records are held. I have tried to make an adding method when I click a save button though it doesn't save the data when you press the button or if it does it doesn't display it. The data is being shown in a tableView
here is the code for the save button:
-(void)savePatient:(id)sender {
LSAppDelegate *delegate = (LSAppDelegate *)[[UIApplication sharedApplication] delegate];
NSMutableArray *patients = delegate.patients;
UITextField *firstnameEntry = (UITextField *)[firstNameCell viewWithTag:777];
UITextField *surnameEntry = (UITextField *)[surnameNameCell viewWithTag:777];
UITextField *dobEntry = (UITextField *)[dobDateCell viewWithTag:777];
UITextField *homeNumberEntry = (UITextField *)[homeNumberCell viewWithTag:777];
UITextField *mobileNumberEntry = (UITextField *)[mobileNumberCell viewWithTag:777];
UITextField *emailAddressEntry = (UITextField *)[emailAddressCell viewWithTag:777];
UITextView *addressEntry = (UITextView *)[addressCell viewWithTag:777];
if (firstnameEntry.text.length > 0) {
Patient *newPatient = [[Patient alloc] init];
newPatient.patientName = firstnameEntry.text;
newPatient.patientSurname = surnameEntry.text;
newPatient.patientDoB = dobEntry.text;
newPatient.patientHomeNumber = homeNumberEntry.text;
newPatient.patientMobileNumber = mobileNumberEntry.text;
newPatient.patientEmail = emailAddressEntry.text;
newPatient.patientAddress = addressEntry.text;
newPatient.patientPicture = nil;
[patients addObject:newPatient];
LSViewController *viewController = delegate.viewController;
[viewController.tableView reloadData];
}
[delegate.navController popViewControllerAnimated:YES];
}
I've found that the issue is here
if (firstnameEntry.text.length > 0) {
please say if you want any more code
Thanks in advance

You need to make sure that your delegate has the proper retain type and not copy as copy in the property returns an array and not an NSMutableArray.
Although your problem of loading data is probably a simple issue of not allocing/initing your array. It would be better to move your patients array to your local class.
Move this property from your delegate to your class.
#property (nonatomic, retain) NSMutableArray *patients;
Do not use copy and do not use NSArray. Also, you need to make sure that somewhere you are instantiating the mutable array. Preferably in the viewDidLoad function.
In your class, somewhere before this viewcontroller is created be sure you create the array.
self.patients = [[NSMutableArray alloc] init];
This assumes you're using ARC. If you're not using ARC be sure to release the array in the dealloc method.
Usually if data isn't coming across it's b/c your array is nil or an NSArray and not NSMutableArray.
I would also add breakpoints in your method above and make sure that your tableView is not nil and that your array is not nil.

Are you sure that [viewController.tableView reloadData]; actually get
executed, i seriously doubt it since you're on a different viewController,
you could try to put the reloatData statement on the viewDidAppear event of your table
controller view after you pop from the editing viewController.

Related

Add Objects From One View Controller To An Array On Another View Controller

I have been trying to figure this out for a while and not coming up with a solution. I have a view controller with a table and the first cell of the table is allocated for a button called "Add Friends". When clicked, it takes you to another view controller with a list of contacts in a table. When you click on a person, it goes back to the other view controller and adds the selected person. This is what I have so far.
ContactsViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
FirstViewController *newVC = [self.storyboard instantiateViewControllerWithIdentifier:#"newVCSegue"];
newVC.peopleArray = [[NSMutableArray alloc] init];
Person *user = [contactsList objectAtIndex:indexPath.row];
NSArray *userKeys = [NSArray arrayWithObjects:#"FirstName", #"LastName", nil];
NSArray *userObjects = [NSArray arrayWithObjects:user.firstName, user.lastName, nil];
NSDictionary *userDictionary = [NSDictionary dictionaryWithObjects:userObjects forKeys:userKeys];
[newVC.peopleArray addObject:userDictionary];
[self.navigationController pushViewController:newVC animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
FirstViewController.h
#property (strong, nonatomic) NSMutableArray *peopleArray;
FirstViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//...
if (indexPath.row == 0) {
contactName.text = #"Add Person";
imgView.image = [UIImage imageNamed:#"plus-icon.png"];
} else {
NSString *firstName = [[peopleArray objectAtIndex:(indexPath.row)-1] objectForKey:#"firstName"];
NSString *lastName = [[peopleArray objectAtIndex:(indexPath.row)-1] objectForKey:#"lastName"];
contactName.text = [NSString stringWithFormat:#"%# %#", firstName, lastName];
}
return cell;
}
This lets me add one friend so far and if I decided to add another to the list, it replaces the first friend added.
What's basically happening is every time you select a new contact, you're recreating the array in the first view controller, hence it is replacing things. You ideally want to try and avoid getting the FirstViewController using the storyboard like that as well, it's pretty bad practice and may well lead to various problems later.
What I'd suggest in this situation is creating a protocol (look at the delegate pattern). This way, what you'd have is :
Use taps "Add Contact"
Contacts list appears, and FirstViewController is set as the delegate
User taps contact to add them
ContactsViewController informs the delegate of the user that was selected
FirstViewController adds the user, and dismissed the view controller
This is generally the approach you'd take, and it's pretty simple to implement. Start with the protocol
#protocol ContactsDelegate
-(void) contactsViewController:(ContactsViewController *)vc didSelectContact:(Person *)person;
#end
Then, make your FirstViewController implement this protocol. To do this, in your header file, in the angle brackets after the name (< >) add ContactsDelegate
In the implementation of FirstViewController, add the new method of the contacts delegate.
In your ContactsViewController.h file, add
#property (nonatomic, assign) NSObject<ContactsDelegate> *delegate;
Then when you display your contacts view controller, set the delegate
userVc.delegate = self;
[self presentModalViewController:userVc];
Then, in the user view controllers didSelectRowAtIndexPath:, simply inform the delegate that you've selected that person
[delegate contactsViewController:self didSelectContact:[contactsList objectAtIndex:indexPath.row]];
And lastly, in your FirstViewController, in the delegate method you added, we need to ADD the user to the list, not re-create the list
[peopleArray addObject:person];
And that should do what you're after :)
From what I understand, you are instantiating a new FirstViewController every time you select a contact in the ContactsViewController. Instead, you should reference the original FirstViewController (perhaps save it before transitioning to ContactsViewController), and use this reference to add the contact to the original array [original.people addObject:userDict]. As long as you make sure to reload the table, this should work.

NSArray Set property not working

Basically what i am trying to do is make a network refresh and fetch objects, store it in a nsmutable array in my app delegate. Then i have a listviewController which uses that mutable array to display data.
Setting nsarray is not working here is the code:
//Appdelegate code called after pulldown to refresh is done on listview:
[ListView setArrayElements:(NSMutableArray*)sortedArray ];
NSLog(#"sortedArray count:%d",sortedArray);
NSLog(#"ListView Array count:%d",[ListView.ArrayElements count]);
Result i get in log : "sortedArray count:12" (which is perfect)&"ListView Array count:0" (this is not the right result)
It's hard to assume without seeing more of your code but how do you define the ArrayElements property? It may not be retaining itself and you may not have initialized it when the ListView object is created.
Let me know if this works;
Make sure ArrayElements is created in your ListView.h like the following:
#property (nonatomic, retain) NSMutableArray *ArrayElements;
Or on -init or -viewDidLoad of your ListView,
self.ArrayElements = [[NSMutableArray alloc] init];
Don't forget to release what you retained:
- (void)dealloc
{
//.....
[ArrayElements release];
[super dealloc];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.mTableView reloadData];
}
use this method
Do not make the UITableView object as a property. Just use tableView object , remove 'self.' portion.
Tell me if it helps!

Storing an int into NSNumber then calling it in a new class

So basically on my ClassA.h I have created a NSNumber called selected. It is also used in #property as well in that .h. Now in ClassA.m I have a table view and when one is selected it goes to another screen. I would like the indexPath.row to save into that NSNumber. (Selected was #synthesized as well in .m)
Where it is being called in ClassA.m is in the didSelectRowAtIndexPath and looks like this.
selected = [NSNumber numberWithInt:indexPath.row];
In the next view is where I would like to recall this code so that it can load a perticular view by code based on the selection. I import ClassA.h and this is the code I put in for ClassB.m
HowTosViewController *h = [[HowTosViewController alloc] init];
if([h.selected intValue] == 0){
content.text = #"0";
}
else if ([h.selected intValue] == 1){
content.text = #"1";
}
I'm assuming my issue is I didn't store it correctly or it isn't calling it correctly. I would prefer to do this using the global variables so if there is an easier way to do this using them I wouldnt mind. I appreciate any help.
Also as a side note. When I go to release selected would it cause any problems or be correct if I did it in ClassB? After it loads the screen from using that number it is no longer needed and another one should be assigned if the person goes back and selects another option.
Thanks :)
EDIT: Forgot to mention what it is doing currently. Currently when clicking on any of the Cells in ClassA it opens the screen and displays 0.
selected = [[NSNumber numberWithInt:indexPath.row] retain];
or if the selected has a retain property... then you do
self.selected = [NSNumber numberWithInt:indexPath.row];
When you do this in ClassB.m
HowTosViewController *h = [[HowTosViewController alloc] init];
that is a new instance, not the same instance where you stored your selected value.
Consider init'ing your ClassB with selected value as well and use that in classB like doing
- (id) initWithSelectedIndex: (NSNumber *) selectedIndex {
if(self = [super init]) {
receivedSelectedIndex = selectedIndex;
}
return self;
}
delcare this receivedSelectedIndex like
NSNumber *receivedSelectedIndex;
#implementation classB
and where you create instance of ClassB you should do like
classB *b = [[classB alloc] initWithSelecedIndex:selected]; //using your selected NSNumber

Problem with NSMutableArray

I declared a NSMutable array and assigned some values to it.
.h
NSMutableArray *imageDetailsFromCategory;
#property (nonatomic, retain) NSMutableArray *imageDetailsFromCategory;
.m
#synthesise imageDetailsFromCategory
in ViewDidLoad:
imageDetailsFromCategory = [[NSMutableArray alloc]init];
//assigning object to Array..working fine.showing two images.
imageDetailsFromCategory = [self getImageDetailsFromCategory:generatedString];
Now my app is loading... I am doing some UI changes with the array. However I want to pass this array on another button click to another class. But when click event is triggered the array shows 0x76779e0"{(int)$VAR Count} like this in the same class I declared the arry. I can't get the array count after the button click.
Can any one tell me how can I access my array. What is the problem?
The method [self getImageDetailsFromCategory:generatedString]; I think returns a autoreleased array. Try using the proper setter for retaining it, like
self.imageDetailsFromCategory = [self getImageDetailsFromCategory:generatedString];
You are overriding your imageDetailsFromCategory variable that you alloc'd in the first line with your second line.
So imageDetailsFromCategory = [[NSMutableArray alloc] init] creates a mutable array… but imageDetailsFromCategory = [self getImageDetailsFromCategory:generatedString]; replaces the previously alloced mutable array with a brand new object.
THat's as if you did int i=5; then i = [self someMethod];: the value 5 would be lost.

Sharing NSMutableArray

Hey everbody, im trying to share a NSMutableArray to another xib. The cartList.codigo is a NSMutableArray from a shared class, according to James Brannan's tutorial (http://www.vimeo.com/12164589).
When i count it, it gives me 1. But when i load the another view, gives me 0.
Whats wrong?
View that adds:
self.produtoCodigo = [[NSMutableArray alloc]init];
[self.produtoCodigo addObject:#"aa"];
CartViewController *carrinho = [[CartViewController alloc] initWithNibName:#"CartViewController" bundle:[NSBundle mainBundle]];
CartList *lista = [[CartList alloc] init];
carrinho.cartList = lista;
carrinho.cartList.codigo = self.produtoCodigo;
NSLog(#"QTD %i", [carrinho.cartList.codigo count]);
View that wants to load the item added:
- (void) viewDidAppear:(BOOL)animated {
self.produtoCodigo = self.cartList.codigo;
NSLog(#"%i", [self.produtoCodigo count]);
[super viewDidLoad];
}
Im loading the CartList class in both.
Thanks!
My guess is that you are not retaining the array, but only assigning it.
Do you retain the array in the view, something like this -
#property (nonatomic, retain) NSMutableArray * produtoCodigo;
the "retain" gives your view controller an ownership on the array and you can use it.
Since I don't have your code that is the best I can do to help.
shani
UPDATE -
Ok. you do retain it but now i see that the "produtoCodigo" array is retained but you dont pass the array in the view controller.
is seems that you can do 2 things:
in your view controller pass the viewController "produtoCodigo" to the view "produtoCodigo".
carrinho.produtoCodigo= self.produtoCodigo;
if you already pass the array to the "cartList" then remove the view "produtoCodigo" array, geter and seter (#synthesize & #property). and in the view did load you can:
produtoCodigo =[NSMutableArray arraryWithArray: self.cartList.codigo];
or if you need to use it later you can :
produtoCodigo =[NSMutableArray alloc]initWithArray: self.cartList.codigo];
and don't forget to release it later in the second option.
Hope this time it will help
shani