Unable to navigate to home page from UIAlertView - iphone

I am using a UITableView to show data, and by using customise button and delete function I am trying to delete selected row. But i want to put an alertview inside that function when UITableView is empty, and by using buttons inside the UIAlertView I am trying to navigate to main page and previous page according to conditions. But it's getting crashed after UITableView is getting empty and I push the delete button with "Program received signal: “SIGABRT".
My code looks like this:
- (IBAction)DeleteButtonAction:(id)sender
{
DMSAppDelegate *d = (DMSAppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(#"Message From Custom Cell Received");
if(d->newtableData.count != 0)
{
NSIndexPath *indexPath = [self.tablevieww2 indexPathForCell:(UITableViewCell *)[[[sender superview] superview] superview]];
NSUInteger row = [indexPath row];
[d->newtableDataQt removeObjectAtIndex:row];
NSLog(#"data removed");
[self.tablevieww2 reloadData];
}
else
{
UIAlertView *alertview=[[UIAlertView alloc] initWithTitle:#"hello" message:#"Warning!!: Table is empty" delegate:self cancelButtonTitle:#"Yes" otherButtonTitles:#"",#"No",nil];
textfieldQty1 = [alertview textFieldAtIndex:0];
textfieldQty1.keyboardType = UIKeyboardTypeNumberPad;
textfieldQty1.keyboardAppearance = UIKeyboardAppearanceAlert;
textfieldQty1.autocorrectionType = UITextAutocorrectionTypeNo;
[alertview show];
[alertview release];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
DMSViewController *bt=[[DMSViewController alloc]initWithNibName:nil bundle:nil];
bt.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:bt animated:YES];
}
else if (buttonIndex == 1)
{
NSString *newqty = [[NSString alloc] initWithFormat:#"%#",textfieldQty1.text];
DMSAppDelegate *d= (DMSAppDelegate *)[[UIApplication sharedApplication] delegate];
[d->newtableDataQt replaceObjectAtIndex:slCell1 withObject:(id)newqty];
NSLog(#"tb%#",d->newtableDataQt);
[self.tablevieww2 reloadData];
int total1=0;
for ( int i=0 ; i < [d->newtableDataQt count];++i )
{
NSString *string = [d->newtableDataQt objectAtIndex:i];
NSLog(#"string%#",string);
if ([string isEqualToString:#"0"])
{
}
else
{
NSLog(#"newArray%#",d->newtableDataPrice);
NSString *strP=[d->tableDataPrice objectAtIndex:i];
NSInteger sp=[strP integerValue];
NSInteger st=[string integerValue];
total1=total1+st*sp;
NSLog(#"total1%d",total1);
}
}
NSString *newtotal1=[NSString stringWithFormat:#"%d",total1];
DMSAppDelegate *d2 = (DMSAppDelegate *) [[UIApplication sharedApplication] delegate];
d2->totalD = [[NSString alloc] initWithString:newtotal1];
}
}
Please give me some solution. I am trying really hard from yesterday but not getting any success.
Thanks in advance.
#

You need to check two things:-
First:- if(d->newtableData.count != 0)
is the condition and you are not removing the items from newtableData you are removing it from newtableDataQt so thats why your else method is not getting called. because newtableData will never have count =0.
Second thing;-
one thing if your table is empty means that newtableDataQt will contain no values , it will be empty.Now when you click on the delete button, the alert view appears , after that if you click whatever button at index 1 then in your code you have written :-
[d->newtableDataQt replaceObjectAtIndex:slCell1 withObject:(id)newqty];
so newtableDataQt has already be empty before and now you are using it.This might be the reason of crash.
try
if( [newtableDataQt count] >slCell1)
{ [d->newtableDataQt replaceObjectAtIndex:slCell1 withObject:(id)newqty];
}
I hope it might help you.

Related

Checking if word is valid in array

I am using code to check if a word is in my array, if it is I want it to submit it and I have the code for it. If it isn't I want it to pop up a screen. now this all works, the only thing is the screen pops up 2 times, because there are 2 words in my array. here is the code to explain it a little better.
NSArray *searchContacts = [NSArray arrayWithObjects:
#"CADEAU",
#"KADERZ",nil];
NSString *myContact = labelsText.text;
for (NSString *contact in searchContacts) {
if ([contact isEqualToString:myContact]) {
this is where I put in my words, CADEAU & KADERZ in this case. When I put one of these words into labelsText.text it does exactly what I want. but for the else statement if the labels text.text word is not CADEAU or KADERZ, it pop ups a screen:
else {
UIAlertView *alert = [[UIAlertView alloc]
This screen will pup up 2 times now, so i'll have to press dismiss 2 times, how would I fix this to just have to press dismiss one time no mather how many words are in the array?
It would be more efficient to use an NSSet, but even if you use an NSArray, you can simply call containsObject: instead of looping through the collection yourself.
if (![searchContacts containsObject:myContact]) {
//show alert...
}
Put a break; after the code showing your alert:
for (NSString *contact in searchContacts) {
if ([contact isEqualToString:myContact]) {
// do something
} else {
// show screen
break;
}
}
This will 'break' out of the loop.
I think you want something like this:
BOOL contactFound = NO;
for (NSString *contact in array)
{
if ([contact isEqualToString:myContact])
{
contactFound = YES;
break;
}
}
if (!contactFound)
UIAlertView *alert = [[UIAlertView alloc]...
Use a break after your UIAlertView.
For example:
for (NSString *contact in searchContacts) {
if ([contact isEqualToString:myContact]) {
//do what you want to do
}
else{
UIAlertView *alert = [[UIAlertView alloc] init];
[alert show];
break; //leave for()
}
}
Or use that:
searchContacts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([contact isEqualToString:myContact]) {
//do what you want to do
}
else{
UIAlertView *alert = [[UIAlertView alloc] init];
[alert show];
*stop = YES; //stop enumeration
}
}

How to call a variable with a value calculated from one method in another method?

My code does a calculation upon a button press in "IBAction" and returns the result in a string as the "message" in "UIAlertView".
else{
NSString *str = [[NSString alloc] initWithFormat:#"You require an average GPA of at least %.2f to achieve your Goal of %#", gpagoal, (NSString *)[myPickerDelegate.myGoal objectAtIndex: [myPicker selectedRowInComponent:0]]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Nothing is Impossible"
message:str
delegate:self
cancelButtonTitle:#"Good Luck"
otherButtonTitles:#"Tweet",nil];
//show alert
[alert show];
[alert release];
NSLog(#"All Valid");
}
i have a problem of how to pull the "gpagoal" value from the calculation's "IBAction" method.
below is the code for the standalone button for tweeting, which works if i am able to port over the gpagoal value from the other method.
- (IBAction)sendEasyTweet:(id)sender {
// Set up the built-in twitter composition view controller.
TWTweetComposeViewController *tweetViewController = [[TWTweetComposeViewController alloc] init];
// i have problem trying to pull the result "gpagoal" from the calculation's "IBAction" method as i dunno how to pull out variable from a method to another method.
NSString *str2 = [[NSString alloc] initWithFormat:#"I need an average GPA of at least %.2f this semester to achieve my Goal of %#", gpagoal, (NSString *)[myPickerDelegate.myGoal objectAtIndex: [myPicker selectedRowInComponent:0]]];
// Set the initial tweet text. See the framework for additional properties that can be set.
[tweetViewController setInitialText:str2];
// Create the completion handler block.
[tweetViewController setCompletionHandler:^(TWTweetComposeViewControllerResult result) {
//NSString *output;
switch (result) {
case TWTweetComposeViewControllerResultCancelled:
// The cancel button was tapped.
//output = #"Tweet cancelled.";
NSLog(#"Tweet cancelled");
break;
case TWTweetComposeViewControllerResultDone:
// The tweet was sent.
//output = #"Tweet done.";
NSLog(#"Tweet done");
break;
default:
break;
}
// Dismiss the tweet composition view controller.
[self dismissModalViewControllerAnimated:YES];
}];
// Present the tweet composition view controller modally.
[self presentModalViewController:tweetViewController animated:YES];
}
You simply need a variable that is available throughout your class
// ViewController.h
...
#interface ViewController : UIViewController {
double gpagoal;
}
Make sure it is properly initialized and updated as needed.

Why can't a Double value stored as Object in NSUserDefault is not reflected in UITableViewCell?

I am trying to store Double Value in NSUserDefault But though i am able to store it (as my NSLog value shows true value), when I tried to reload UITableView, its Cell value is not updated with current value in userdefault.
This weird behavior happens only when i call my setUserDefaults method from delegate method of UIAlertView
Why such weird behavior happens??
Here is my code:
- (void)setUserDefaults
{
NSLog(#"setUserDefault : empArray: %d, empCount: %d",empArray.count, empCount);
NSMutableDictionary *empData = [[NSMutableDictionary alloc] init];
if (empArray.count>1)
empData = [empArray objectAtIndex:(empCount-1)]; // because empCount starts from 1. and empArray[0] = empCount 1
else
empData = [empArray objectAtIndex:0];
[userDefault setObject:[NSString stringWithFormat:#"%.2f",[empData objectForKey:#"salary"]] forKey:#"salary"];
NSLog(#"setUserDefaults: salary=%.2f",[[empData objectForKey:#"salary"] doubleValue]);
[empData release];
[self.tblView reloadData];
}
Delegate method of UIAlertView goes as below:
-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger) buttonIndex
{
if (alertView.tag == 1) // btnRemoveEmpPressed.
{
if(buttonIndex==0)
{
NSLog(#"buttonIndex 0");
}
else
{
NSLog(#"empRemovedPressed OK, buttonIndex 1, empArray Count %d, empCount %d",empArray.count, empCount);
// [empArray removeObjectAtIndex:(empCount)];
empCount -= 1;
lblTitle.text = [NSString stringWithFormat:#"Employee %d",empCount];
[self setUserDefaults];
}
// [tblView reloadData];
}
else if (alertView.tag == 2)
{
if (buttonIndex==1)
{
[self resetUserDefaults];
empCount = 1;
[empArray removeAllObjects];
lblTitle.text = [NSString stringWithFormat:#"Employee %d",empCount];
}
}
}
You should use the setDouble:forKey: method of NSUserDefaults and let it manage the value for you. Also synchronize the NSUserDefaults in order to save the value for later usage.
You aren't using doubleValue when setting user defaults. Either do that or, as herz says, use the setDouble method.
You aren't calling synchronize on your defaults object after updating it
Don't release empData, you didn't retain it
I'm assuming userDefault is set up elsewhere and it is not nil when you are using it?

For push notifications: how do I add action to alert view to change views?

So I have push notifications sending to my application.
The code that triggers the alert is in my app delegate file (I think thats where it is supposed to go?)
How do I make an action for my alert button so that I can change to a different view?
// Set Below code in your App Delegate Class...
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
// Call method to handle received notification
[self apnsPayloadHandling:userInfo];
}
-(void) apnsPayloadHandling:(NSDictionary *)userInfo{
// Example Payload Structure for reference
/*
remote notification: {
acme1 = 11114;
aps = {
alert = {
"action-loc-key" = "ACTION_BUTTON_TITLE";
"loc-args" = ("MSG_TEXT");
"loc-key" = "NOTIFICATION_DETAIL_PAGE";
};
badge = 10;
sound = "chime";
};
}
*/
//======================== Start : Fetching parameters from payload ====================
NSString *action_loc_key;
NSArray *loc_args_array;
int badge;
NSString *sound=#"";
NSArray *payloadAllKeys = [NSArray arrayWithArray:[userInfo allKeys]];
// getting "acme1" parameter value...
if([payloadAllKeys containsObject:#"acme1"]){
acme1 = [userInfo valueForKey:#"acme1"]; // getting "ID value" as "acme1"
}
NSString *localizedAlertMessage=#"";
// getting "aps" parameter value...
if([payloadAllKeys containsObject:#"aps"]){
NSDictionary *apsDict = [NSDictionary dictionaryWithDictionary:[userInfo objectForKey:#"aps"]];
NSArray *apsAllKeys = [NSArray arrayWithArray:[apsDict allKeys]];
if([apsAllKeys containsObject:#"alert"]){
if([[apsDict objectForKey:#"alert"] isKindOfClass:[NSDictionary class]]){
NSDictionary *alertDict = [NSDictionary dictionaryWithDictionary:[apsDict objectForKey:#"alert"]];
NSArray *alertAllKeys = [NSArray arrayWithArray:[alertDict allKeys]];
if([alertAllKeys containsObject:#"action-loc-key"]){
action_loc_key = [alertDict valueForKey:#"action-loc-key"]; // getting "action-loc-key"
}
if([alertAllKeys containsObject:#"loc-args"]){
loc_args_array = [NSArray arrayWithArray:[alertDict objectForKey:#"loc-args"]]; // getting "loc-args" array
}
if([alertAllKeys containsObject:#"loc-key"]){
loc_key = [alertDict valueForKey:#"loc-key"]; // getting "loc-key"
}
if([loc_args_array count] == 1){
localizedAlertMessage = [NSString stringWithFormat:NSLocalizedString(loc_key, nil),[loc_args_array objectAtIndex:0]];
}
else if([loc_args_array count] == 2){
localizedAlertMessage = [NSString stringWithFormat:NSLocalizedString(loc_key, nil),[loc_args_array objectAtIndex:0],[loc_args_array objectAtIndex:1]];
}
else if([loc_args_array count] == 3){
localizedAlertMessage = [NSString stringWithFormat:NSLocalizedString(loc_key, nil),[loc_args_array objectAtIndex:0],[loc_args_array objectAtIndex:1],[loc_args_array objectAtIndex:2]];
}
}
else{
localizedAlertMessage = [apsDict objectForKey:#"alert"];
}
}
if([apsAllKeys containsObject:#"badge"]){
badge = [[apsDict valueForKey:#"badge"] intValue]; // getting "badge" integer value
}
if([apsAllKeys containsObject:#"sound"]){
sound = [apsDict valueForKey:#"sound"]; // getting "sound"
}
}
//======================== Start : Handling notification =====================
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
if (state == UIApplicationStateActive){ // application is already open
if(apnsAlert){
apnsAlert = nil;
}
if(action_loc_key){ // View Button title dynamic...
apnsAlert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:#"%# %#",[[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleDisplayName"],NSLocalizedString(#"NOTIFICATION", nil)] message:localizedAlertMessage delegate:self cancelButtonTitle:NSLocalizedString(#"CANCEL", nil) otherButtonTitles: NSLocalizedString(action_loc_key, nil),nil];
}
else{
apnsAlert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:#"%# %#",[[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleDisplayName"],NSLocalizedString(#"NOTIFICATION", nil)] message:localizedAlertMessage delegate:self cancelButtonTitle:NSLocalizedString(#"OK", nil) otherButtonTitles:nil];
}
[apnsAlert show];
}
else{ // application is in background or not running mode
[self apnsViewControllerRedirectingFor_loc_key:loc_key with_acme1:acme1];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the OK/Cancel buttons
if(alertView == apnsAlert){
if (buttonIndex == 1){
[self apnsViewControllerRedirectingFor_loc_key:loc_key with_acme1:acme1];
}
}
}
-(void) apnsViewControllerRedirectingFor_loc_key:(NSString *)loc_key_para with_acme1:(NSString *)acme1_para{
if([loc_key_para isEqualToString:#"NOTIFICATION_DETAIL_PAGE"]){
DetailPageClass *detailPage = [[DetailPageClass alloc] initWithNibName:#"DetailPageClass" bundle:nil];
[self.navigationcontroller pushViewController:detailPage animated:YES]; // use nav controller where you want to push...
}
else if([loc_key_para isEqualToString:#"NOTIFICATION_MAIN_PAGE"]){
}
...
}
To change the title of the button, use the action-loc-key key in the notification dictionary (see this section of the guide).
To do something when the notification is tapped, you can implement a few methods in your app delegate: Handling notifications.

Dealing with editable items in a filtered UITable with an NSMutableArray copy

I have a UITable with a datasource that is set to a 'copy' of the original data. I use this copy to displayed filtered results (either 'All' or only those that are 'checked' with a UISwitch in each row). My logic for doing the filtering is here:
-(void)filterItems {
[tableData removeAllObjects];
if (checkedOrNotSwitch.selectedSegmentIndex == 0) {
[tableData addObjectsFromArray:self.defaultChecklistItemsArray];
} else {
for (NSMutableDictionary *sectionDict in self.defaultChecklistItemsArray) {
NSMutableArray *newItemsArray = [[NSMutableArray alloc] init];
[newItemsArray removeAllObjects];
for (NSMutableDictionary *itemDict in [sectionDict objectForKey:#"categoryItems"]) {
if ([[itemDict objectForKey:#"isComplete"] boolValue]) {
[newItemsArray addObject:itemDict];
}
}
if ([newItemsArray count] > 0) {
NSMutableDictionary *newSectionDict = [[NSMutableDictionary alloc] initWithDictionary:sectionDict];
[newSectionDict setObject:newItemsArray forKey:#"categoryItems"];
[tableData addObject:newSectionDict];
[newSectionDict release];
}
}
}
[checklistTable reloadData];
}
The filtering itself now works correctly. In my custom cell, each row has a UISwitch. The switch runs this function when its changed:
-(IBAction) switchValueChanged{
NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];
[self.parentController updateCompletedStatusAtIndexPath:indexPath toStatus:isCompleted.on];
}
The function above is in the class for the tableviewcell itself. The function I call in the superview is this:
-(void)updateCompletedStatusAtIndexPath:(NSIndexPath *)indexPath toStatus:(BOOL)status{
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSMutableDictionary *currentsection = [[NSMutableDictionary alloc] initWithDictionary:[tableData objectAtIndex:section]];
NSMutableArray *itemsArray = [[NSMutableArray alloc] initWithArray:[currentsection objectForKey:#"categoryItems"] copyItems:YES];
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] initWithDictionary:[itemsArray objectAtIndex:row]];
NSLog(#"BOOL = %#\n", (status ? #"YES" : #"NO"));
[tempDict setValue:[NSNumber numberWithBool:status] forKey:#"isComplete"];
[itemsArray replaceObjectAtIndex:row withObject:tempDict];
[currentsection setValue:itemsArray forKey:#"categoryItems"];
[tableData replaceObjectAtIndex:section withObject:currentsection];
[tempDict release];
[itemsArray release];
[currentsection release];
[checklistTable reloadData];
}
Before I implemented the filtering and used the logic above on self.defaultChecklistItemsArray directly, it worked and saved the data when the switch was flipped.
Now when I first enter the app, it loads the array of data from nsuserdefaults. I navigate to the view with the table and it displays the data correctly there with the UISwitches all in the correct position given the data (some on, some off). When I tap one of the switches, then click the segmentedcontrol that does the filtering, the data reverts back to the state it was loaded in, implying that the flipping of the switch did not actually effect the data at all (even though I don't think I did a deep copy anywhere here so I figured it should be doing the right thing). Any suggestions?