duplicates data while adding into table - iphone

In my app when i insert data by clicking on add button data will be inserted into database and table.record will be inserted perfectly but when i add that data into table it duplicates the database data..here is the code:
NSString *insertData=[NSString stringWithFormat:#"insert into tbl_Bills(Amount,Note,Due_On) values ('%f','%#','%#')",addAmountInDouble,val,due];
[database executeQuery:insertData];
NSLog(#"inert query: %#",insertData);
NSLog(#"value inserted");
NSString *countQuery = [NSString stringWithFormat:#"Select Bill_Id,Entry_Date,Amount,Note,Due_On from tbl_Bills"];
NSArray *countArray1 = [database executeQuery:countQuery];
NSLog(#"Query:%#",countArray1);
[BillTableArray addObjectsFromArray:countArray1];
NSLog(#"Count array %#",countQuery);
NSLog(#"table array:%#",BillTableArray);
[database close];
[table reloadData];
count array is fine but table array duplicates the value..i also initialize table array in viewDidLoad() method.

first of all you need to clear your table array before adding new objects :
[BillTableArray removeAllObjects];
after add new updated objects :
[BillTableArray addObjectsFromArray:countArray1];

This is because you are not clearing data out of BillTableArray before adding the new data into it. You are rerunning your query across the entire table - thus retrieving all of your records again, including the ones you've already set up in BillTableArray on the initial view load.
The problem is this line:
[BillTableArray addObjectsFromArray:countArray1];
BillTableArray is already loaded with data from your initial viewDidLoad call, but the query you executed retrieves all of this data from the database again, and this line is adding all of those objects to the array for a second time. So you are probably seeing duplicates of everything except the newly added items.
You probably just need to do:
BillTableArray = [countArray1 retain];
or something similar (don't forget to retain/release objects appropriately to ensure you don't lose them or leak them, not sure how BillTableArray is declared.

BillTableArray presumably contains all the data you already had in the table. When you re-query the database to get your added value, you will be returning everything, then adding it all again.
So, either
Specifically add only the new objects to BillTableArray
Change your countQuery to only return the new object
Replace all the contents of BillTableArray with countArray1

[BillTableArray addObjectsFromArray:countArray1]; adds all the objects from array countArray1. So I guess the existing objects in BillTableArray are not removed before adding the new objects. This creates duplicates. To remove duplicates, just remove all the objects of BillTableArray and then add the objects from countArray1.
Just a small note, please make sure you name the variables starting with a lower case alphabet.

Related

How to keep UITableView's datasource ordered in response to user moving rows around?

I have a UITableView and one of its sections is managed by a NSFetchedResultsController. It fetches core data objects and keep them sorted by the "order" attribute:
object with order 1
object with order 2
object with order 3
The requirement that I'm facing is that the user can move rows around. After move:
object with order 2
object with order 1
object with order 3
What do I need to do to ensure that the managed objects in core data reflect changes in order resulting from user moving table view rows around? When I'm working with GMGridView, there's a callback that exchanges two objects. In such case, changing their order works, but I do not see such function for a UITableView.
Would I need to manually change the order attribute for all objects that exist below the moved row?
You can use this:
- (NSIndexPath *) tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
Plus re-ordering your data-source, by exchanging the objects order.
You need to store an association between the fetched object and the 'row order'. You order the rows based on row order; the row order defaults to your 'order' attribute. When the user moves a row, you update the 'row order' as well.
You can maintain the association either in the CoreData object itself (add another attribute) or by mapping the fetched object to its row order (in NSUserDefaults or in just a NSDictionary).
Moving rows around does not just affect the order attribute of itself but all the rows behind it. A work around I have found is to copy the fetch request objects to an nsmutablearray then moving the object within this array. Then running a for loop and updating the order attribute in each object then saving the managed object context. Then reload the uitableview. This seems like a lot of work but currently moving objects in a fetch request is not automatic like insert and delete. I hope this helps!

How can i save the order of an NSMutableArray

I have an NSMutableArray and I change the order of the contents of it. How can I save the order of it in core data without using a relation ship, or should I use NSUserDefaults?
Why not have a second array that is a copy of the first one at the time that you want to preserve its order? It need not be a mutable array - use [myArray immutableCopy]
If you don't want to copy all the items in the array for memory reasons, perhaps store the location as an NSInteger? Have the first array contain the items, and the second array contains indexes for the first array.

how to delete data from same named but stored in different NSMutablerArray by referencing its name?

i have created one table view in which i have provided searching & deleting facility. My problem is that when i am not in searching mode the data is going to be deleted properly & shows the table properly after deleting data. but my problem is that i have two NSMutableArrays one is original and second one is searched NSMutableArray so when i delete data from searched Array at that time i want to delete data from original array also.
NSString *str = [searchedName objectAtIndex:indexPath.row];
NSLog(#"str:=%#",str);
[searchedName removeObjectAtIndex:indexPath.row];
[arrName removeObjectIdenticalTo:str];
so here my point is that i can't delete original data with use of removeObjectAtIndex:index.path because the searched array count will be different from original array count so from original array it will delete another value witch i have not deleted from searched value.
did you get my point? please mention me if you don't get my point.
how can i implement like this? please guide me.
You can first search the index from the original array
int index = [arrName indexOfObject:str];
If you have unique name in your array then delete that object directly like below...
[arrName removeObject:str];

Loading data objects into an NSArray causes a painfully slow startup

I have a Core Data database of about 500 objects. These objects are 'cards' that will be viewed and modified by the user. When a user modifies the card, an attribute called 'groupNumber' will change.
The order of these cards in each group is very important and is determined by the user. I load the database objects into an array. When a user makes a change, I save the order of the array into a plist using the 'title' attribute.
My problem comes when the app is relaunched. I need to load the group array in the order it was saved in. But when I use the plist to do a fetch request, it is painfully slow.
The slow code is:
// get array from plist sorted by 'title'
NSMutableArray *group1Temp = [plistData objectForKey:#"group1ArrayData"];
for (int i = 0; i < [group1Temp count]; i++) {
// set predicate to 'title' attribute
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"title == %#", [group1Temp objectAtIndex:i]];
// load filtered database object into temp array
NSArray *temp = [self.vocabDeckArray filteredArrayUsingPredicate:predicate];
[self.group1Array addObjectsFromArray:temp];
}
When this executes 500 times, it is just too slow. If I could save an NSArray of the database objects themselves into a plist, then I wouldn't need to do a predicate search, but it seems I can't do that.
I'm thinking my entire approach to this has been wrong. How can I save/load the order of an array of database objects in a faster way? Is loading database objects into an array itself bad practice?
Thanks for any help!
Traversing the entire vocabDeckArray and filtering it once for each object in group1Temp is very inefficient. There are any number of ways you could rebuild this sorted data set in less than O(n^2) time.
One easy option might be to store a dictionary with the object's titles as keys and their position in the array as values. That way you can construct an array of known length and put every object in vocabDeckArray into the correct position in a single pass (get first object from vocabDeckArray, lookup where in belongs in group1Array from the dictionary, insert into group1Array, move on to next object). That's still not particularly fast but it seems like a minimal change to your current behavior.
In addition consider the number of method calls within your loop. self.vocabDeckArray and self.group1Array are method calls which you make on every iteration of your loop even though they always return the same objects. Keeping local variables which reference those objects instead would save you the overhead of 2 method calls on every iteration.

How can I return the count of objects for an FRC fetch?

I am trying to use the count of objects from my FRC fetch so that I can create an "Add" cell after all of my fetched objects have been listed in a UITableView. Is there a method for returning the number of objects fetched? I can only find a method that returns the count of sections for a given FRC.
Simplistically, you You want a count of fetchedObjects. So:
[[myFRC fetchedObjects] count];
The problem that you're going to have with adding an additional cell, is that every time the table ask for the count of sections and rows, you're going to have add 1 to the count so the table knows to add the extra row.
Bjarne Mogstad is correct. It's quicker and cleaner to put the add element in a header or footer for the table itself. That way, the table directly and cleanly represents the data structure without having to constantly adjust for the phantom row.
The easiest way to do this is by setting the tableFooterView property of your table view. The footer view will be displayed below the last table view cell.