Repopulate UITableView with New Data - sql

I am implementing a search functionality using UIAlertView that will search a SQL Table for a match and repopulate the UITableView. So far I have this code below. "results" is array of match returned data from the search query. Then, I checked if the "elements" are empty which means it does not match any item in SQL Table. If it does then I would like to erase the data currently on UITableView and replace with the "results" data.
Here is my code so far:
NSUInteger *elements = [results count];
if(elements == 0)
{
UIAlertView *av = [[UIAlertView alloc]initWithTitle:#"Item Not Found" message:#"Sorry the item was not found" delegate:self cancelButtonTitle:#"Cancel"
otherButtonTitles:nil, nil];
[av show];
}
if(elements >= 1)
{
//Repopulate UITableView with Data
self.itemTitles = itemstitle;
self.itemPrices = itemsprice;
self.itemCategory = itemscategory;
}
Note: I tried to use [tableView reloadData] but not sure how to implement it in this case.
Thanks in advance for the help.

Related

Retrieving values from a large dictionary at runtime in a MacOS app

I come from a mostly ruby/js background. Our MacOS app hasn't been updated in a few years and there's no one on the team right now that does ObjC full time. I've always been curious, so I'm taking a crack at a ticket for a tiny feature in our MacOS app.
Here's what it boils down to:
We have a view with 5 columns, one of which displays an item's ID. We want to start displaying the facility name associated with that ID, which we currently have in a giant (~16k lines) json file.
Here's how the columns are initialized when we configure the UI:
NSTableColumn * checkedColumn = [[NSTableColumn alloc] initWithIdentifier:#"active"];
[[checkedColumn headerCell] setStringValue:#"Active"];
[checkedColumn setWidth:30];
[checkedColumn setEditable:YES];
[inventoryTable addTableColumn:checkedColumn];
NSTableColumn * idColumn = [[NSTableColumn alloc] initWithIdentifier:#"id"];
[[idColumn headerCell] setStringValue:#"ID"];
[idColumn setWidth:120];
[idColumn setEditable:NO];
[inventoryTable addTableColumn:idColumn];
NSTableColumn * ownerColumn = [[NSTableColumn alloc] initWithIdentifier:#"owner"];
[[ownerColumn headerCell] setStringValue:#"Owner"];
[ownerColumn setWidth:120];
[ownerColumn setEditable:NO];
[inventoryTable addTableColumn:ownerColumn];
NSTableColumn * countColumn = [[NSTableColumn alloc] initWithIdentifier:#"count"];
[[countColumn headerCell] setStringValue:#"Count"];
[countColumn setWidth:120];
[countColumn setEditable:NO];
[inventoryTable addTableColumn:countColumn];
NSTableColumn * pendingColumn = [[NSTableColumn alloc] initWithIdentifier:#"pending"];
[[pendingColumn headerCell] setStringValue:#"Pending"];
[pendingColumn setWidth:70];
[pendingColumn setEditable:NO];
[inventoryTable addTableColumn:pendingColumn];
I added the following to create the new column:
NSTableColumn * facilityColumn = [[NSTableColumn alloc] initWithIdentifier:#"facility"];
[[facilityColumn headerCell] setStringValue:#"Facility"];
[facilityColumn setWidth:120];
[facilityColumn setEditable:NO];
[inventoryTable addTableColumn:facilityColumn];
The original rendering in the tableView was this:
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
IVClient * client = [allClients objectAtIndex:row];
if ([[tableColumn identifier] isEqualToString:#"id"]) {
return PropToString(client.id);
} else if ([[tableColumn identifier] isEqualToString:#"owner"]) {
return PropToString(client.owner);
} else if ([[tableColumn identifier] isEqualToString:#"count"]) {
return [NSNumber numberWithInt:client.count];
} else if ([[tableColumn identifier] isEqualToString:#"pending"]) {
return [NSNumber numberWithBool:client.pending];
} else if ([[tableColumn identifier] isEqualToString:#"active"]) {
return [NSNumber numberWithBool:client.active];
}
return nil;
}
and i added a condition to match the new value:
else if ([[tableColumn identifier] isEqualToString:#"facility"]){
return FacilityNameFromID(client.id);
}
I have only a surface level grasp of how to interact with Obj C data structures, but it seems like this should be pretty straightforward and i have to either:
1) Store the chunk of data in a dictionary and check for an ID match every time we render rows
or
2) Store it in a db and query by ID.
It seems like holding that much data in a dictionary is excessive but I'm going into this pretty blind. If I were in my comfort zone and building a backend for an api with these same specs, I'd definitely go the db route. I'm just not familiar with CoreData whatsoever.
Would #1 at least be realistic for a smaller dataset?
16K lines, or even records, does not qualify as "giant" or even particularly large, in my eyes. A dictionary should be adequate. Certainly, it's where you should start before measuring and determining if the performance is a real problem. (Premature optimization and all that.)
After that, the first optimization I'd try would be to make a read-only property of IVClient called facilityName whose getter implementation does the lookup with caching. That is, something like:
- (NSString*) facilityName
{
if (!_facilityName)
_facilityName = FacilityNameFromID(self.id);
return _facilityName;
}

Select UIPickerview based on matching a string from coredata

I have a form that once a user submits, it should reload the view (but change a few things).
On this form there is a UIPickerview (_tripPicker) that has 2 locations a starting location and an end location (2 components to the pickerview).
I have it saving to the appropriate database and all that - but when it reloads (when the user clicks save) I want the pickerview to 'reset', and the first location (begSchool), to match the users second location (endSchool) that they just saved to coredata.
For example: Lets say user went from PointB to pointC (component 0 & 1 respectively in the pickerview); when they click save, I would like component 0 to display "PointC" and for the second component to just display the list of points to go to (resetting it to how it originally loads).
I've attempted to try and do some of this matching strings, but I'm running into issues with it.
Here is the logic where I do this:
//Save the data & reload View
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
//Reset the pickerview **********THIS LOGIC NEEDS WORK**********
//Check to see if there is previous UserMiles entered - if so, set beg_school to appropriate name
// Get the local context
NSArray *tripsSorted = [UserMiles MR_findAllSortedBy:#"driven_date" ascending:NO];
if (!tripsSorted || !tripsSorted.count){
//if no previous trips have been entered - set the school list to default
begSchoolLabel.text = [_schoolArray1 objectAtIndex:[_tripPicker selectedRowInComponent:0]];
} else {
UserMiles *lastTrip = [tripsSorted objectAtIndex:0];
NSString *preValue = lastTrip.end_school;
begSchoolLabel.text = preValue;
NSUInteger *currentIndex = [_schoolArray1 indexOfObject:preValue]; //Error/warning that incompatible integer to point conversion
[_tripPicker selectRow:currentIndex inComponent:0 animated:YES]; //Error/warning here that incompatible point to integer conversion
NSLog(#"LastTrip.endSchool = %#", lastTrip.end_school);
}
//Set end school labels for the second component in the picker
endSchoolLabel.text = [_schoolArray2 objectAtIndex:[_tripPicker selectedRowInComponent:1]];
NSLog (#"saveInBackground: finished!");
}];
[self.view setNeedsDisplay];
lastTrip.end_school gets me the appropriate name of the school from component 1 of the pickerview, I just need to figure out how to match that with the appropriate value from the array that is loading the pickerview and make it selected in the pickerview. The text currently displays the appropriate name, but the pickerview does not show any change.
Please let me know if I need to clarify or what other code you need to see - thanks in advance.
I was able to solve this by first finding the indexValue in the array by matching the string against the Objects in the array.
I ended up with this:
//Save the data & reload View
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
//Reset the pickerview **********THIS LOGIC NEEDS WORK**********
//Check to see if there is previous UserMiles entered - if so, set beg_school to appropriate name
// Get the local context
NSArray *tripsSorted = [UserMiles MR_findAllSortedBy:#"driven_date" ascending:NO];
if (!tripsSorted || !tripsSorted.count){
//if no previous trips have been entered - set the school list to default
begSchoolLabel.text = [_schoolArray1 objectAtIndex:[_tripPicker selectedRowInComponent:0]];
} else {
UserMiles *lastTrip = [tripsSorted lastObject];
NSString *preValue = lastTrip.end_school;
begSchoolLabel.text = preValue;
int indexValue = [_schoolArray1 indexOfObject:preValue]; //Compares the preValue string to the strings in the array and finds the indexValue of the right match
[_tripPicker selectRow:indexValue inComponent:0 animated:YES]; //Sets the picker to the appropriate value
NSLog(#"LastTrip.endSchool = %#", lastTrip.end_school);
}
//Set end school labels for the second component in the picker
endSchoolLabel.text = [_schoolArray2 objectAtIndex:[_tripPicker selectedRowInComponent:1]];
NSLog (#"saveInBackground: finished!");
}];
[self.view setNeedsDisplay];

Cocoa touch how to run a UIAlertView inside a while loop

I have an int where someone sets how many spellings there are called samount and a int called amountdone and they are both set to 0 like this NSInteger samount = 0;
NSInteger amountdone = 0;at the start. I have a button and when it is clicked it calls the method Startese. The code is
- (IBAction)Startest:(id)sender {
UIAlertView *amount = [[UIAlertView alloc] initWithTitle:#"Amount" message:#"How much spellings are there" delegate:self cancelButtonTitle:#"That amount" otherButtonTitles:nil];
[amount setAlertViewStyle:UIAlertViewStylePlainTextInput];
[[amount textFieldAtIndex:0] setKeyboardType:UIKeyboardTypeNumberPad];
[amount setTag: 0];
[amount show];
}
And I need a UIAlertView to display its self and then add its text in to an array I have got the alertView clickedButtonAtIndex void working like this
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch (alertView.tag)
{
case 0: /* amount alert */
{
samount = [[alertView textFieldAtIndex:0]text];
UIAlertView *spellings = [[UIAlertView alloc]initWithTitle:#"Enter Spelling " message:#"Pleaseenter ONE of the spellings" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[spellings setTag:1];
[spellings setAlertViewStyle:UIAlertViewStylePlainTextInput];
[spellings show];
}
break;
case 1: /* Spellings alert*/{
while (amountdone < samount) {
amountdone = amountdone + 1;
self.myarry = [[alertView textFieldAtIndex:0]text];
}
}
break;
}
}
`
It works the first time but once the while loop activates it freezes the app does anyone know how to fix this
Create method to create and launch your alertView and in clickedButtonAtIndex: method call after delay;
[self performSelector:#selector(yourMethodForLaunchingAlertView:)
withObject:objectOrNill
afterDelay:0.5];
Hope this help.
Well, the reason it is locking up is because amountdone is never set to anything other than the initialization of 0, so amountdone < samount is likely always true, and therefore your while loop continues forever.
When is amountdone suppose to be set?
Edit
I don't think you want a while loop. Based on what you've got
while (amountdone < samount) {
amountdone = amountdone + 1;
self.myarry = [[alertView textFieldAtIndex:0]text];
}
The while loop provides no value, it may as well be an if condition because you're setting the same thing over and over again (which setting NSString to NSArray doesn't make sense either).
I think it's time to take a step back and reevaluate the problem you're solving and your approach. Maybe I can help if you describe the use-case/business requirement.

How to display selected consumables in a table in Objective C

I am having an issue selecting appropriate consumables that I have set up in iTunes Connect to appear in my table in a nib file. (Using Ray Wenderlich's tutorial)
I have set up 11 consumables which are in two distinct sets; coins and categories.
What I want to do is have two buttons, each taking the user to a different table. Depending on the table a different set is displayed.
I have tried for hours to get this to work and I cannot do it; so I bow to the powers of the StackOverflow community to help.
Currently my set is as follows:
NSSet * productIdentifiers = [NSSet setWithObjects:
#"com.ac.scramble.coins1",
#"com.ac.scramble.coins2",
#"com.ac.scramble.coins3",
#"com.ac.scramble.coins4",
#"com.ac.scramble.coins5",
#"com.ac.scramble.category1",
#"com.ac.scramble.category3",
#"com.ac.scramble.category5",
#"com.ac.scramble.category8",
#"com.ac.scramble.category15",
#"com.ac.scramble.category30",
nil];
sharedInstance = [[self alloc] initWithProductIdentifiers:productIdentifiers
which is set up through iTunes Connect with no problem.
The evident problem here is that in my first nib which wants to show 6 rows, it is showing the final six in the list above (not sure why the final six rather than the first six...). This is fine, but in the second nib, which wants to show 5 rows, it is showing the final five from the list above. I don't want that - I want it to display the top five (the coins).
I've tried splitting the NSSet up into two and passing through but I cannot get that to work. I don't know if I can in the code somewhere specify which rows of the set I want to display. The pertinent code (I believe) which is probably where I need to do some trickery is:
- (void)reload {
_products = nil;
[self.table2 reloadData];
[[RageIAPHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) {
if (success) {
_products = products;
[self.table2 reloadData];
}
//[self.refreshControl endRefreshing];
}];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
SKProduct *product = (SKProduct *) _products[indexPath.row];
cell.nameLabel.text = product.localizedTitle;
NSLog(#"Localized title: %#", product.localizedTitle);
cell.thumbnailImageView.image = [UIImage imageNamed:[thumbnails3 objectAtIndex:indexPath.row]];
cell.descriptionLabel.text = [descriptions3 objectAtIndex:indexPath.row];
[_priceFormatter setLocale:product.priceLocale];
//cell.detailTextLabel.text = [_priceFormatter stringFromNumber:product.price];
cell.progressLabel.text = [_priceFormatter stringFromNumber:product.price];
cell.descriptionLabel.text = product.localizedDescription;
}
Thanks to all in advance.
I managed to work out the answer and it was indeed splitting the set up. This may not be the most efficient way of doing this but I took the Set of 11 elements and depending on which one I wanted I either used the removeLastObject or removeObjectAtIndex[0] methods to obtain what I wanted. Thanks to everyone's help!

Objective C - Random XIB pick

I have already posted another question about this, but no one seemed to know how to do this.
I want my app to pick a random XIB file for me, but dont use the ones that have already been randomly picked.
So heres what i have set up as of right now, it seems to work, but i have to keep pressing the button over and over until it finds one that hasnt be used.
-(IBAction)continueAction:(id)sender{
random = arc4random() % 2;
if (random == 0 && usedQ2 == 0) {
Question_2 *Q2 = [[Question_2 alloc] initWithNibName:#"Question 2" bundle:nil];
Q2.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:Q2 animated:YES];
[Q2 release];
}
else if (random == 1 && usedQ3 == 0) {
Question_3 *Q3 = [[Question_3 alloc] initWithNibName:#"Question 3" bundle:nil];
Q3.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:Q3 animated:YES];
[Q3 release];
}
}
So as you can see i have it pick from a random number, and from their find the one that it matches.
Then you can see i have another part of my if statement that is checking to make sure it hasn't been used before.
each NIB file has its own usedQ(whatever Q it is), and when that Nib file is loaded it puts that usedQ as 1.
I think i could get by doing this, but in order to get rid of the constant button pushing, i will have to put loads of else statements with more else statements in them.
I have also tried running the
random = arc4random() % 2;
in a while statement and a for statement, i hoped that it would keep looking for a number until one that hasn't be used was found with no luck.
Any help? thanks!
Why don't you make a mutable array
and populate it with the names of all
your nibs.
Then read the count of the array and
generate a random number in that
range.
Extract the nib name at that index
and remove it from the array.
repeat steps 2-3.
//Setup your list at an appropriate place
NSMutableArray *nibs
= [[NSMutableArray alloc] initWithObjects: #"One Nib", #"Another
Nib", #"Last Nib", nil];
self.unusedNibs = nibs; //This should be a property you declare in
your header.
[nibs release];
-(IBAction)continueAction:(id)sender{
int random = arc4random() % [self.unusedNibs count];
NSString
*nibName = [self.unusedNibs objectAtIndex: random];
[self.unusedNibs removeObjectAtIndex:
random];
//Load nib here.
}