uialertview and delegate (delayed in code) - iphone

I'm checking if file already exists and if it is, I'm alerting the user if he wants o replace the file. I'm using alert view and a delegate.
However when i run it using the simulator by the time the user selects YES or NO the program already run pass it and the blnVal has NO value regardless
I'm not sure what i'm missing here.?
(I searched the database here but couldn't find any related specific question)
-(void) chkFile2Save
{
short tst;
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* foofile = [documentsPath stringByAppendingPathComponent:pln2Save.text];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];
if(fileExists)
{
blnVal=NO;
[self AskFileSave];
}
//blnVal always NO for whatever reason ... ?
if(blnVal==NO)
tst=5;
//...
else {
tst=10;
//..
}
}
- (void) AskFileSave
{
UIAlertView *alertFileSave = [[UIAlertView alloc] initWithTitle:#"" message:#"File already exists. Override the file with current data?" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alertFileSave setTag:10];
[alertFileSave show];
[alertFileSave release];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
//override file exists
if([alertView tag]==10)
{
if(buttonIndex == 1)
{
blnVal=YES;
}
else
{
blnVal=NO;
}
}
}

you are calling
[self AskFileSave];
that will execute
- (void) AskFileSave
than the execution will go back to :
//blnVal always NO for whatever reason ... ?
if(blnVal==NO)
tst=5;
//...
else {
tst=10;
//..
}
You should move that part of the code to delegate method, There you have the option what the user selected, because the UIAlerView will not stop the code execution.
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
//override file exists
if([alertView tag]==10)
{
if(buttonIndex == 1)
{
blnVal=YES;
tst = 10;
}
else
{
blnVal=NO;
tst=5;
}
}
}
I hope it helps!

Related

how to call a method within a method in iphone

i am facing problem when i call method within method of another class like this i have method for button when someone click on button
//within ViewController.m button method
-(IBAction)login:(id)sender
{
DBHelper *objdb = [[DBHelper alloc] init];
[objdb loginnow:textname.text andpassword:textpassword.text];
}
and this button method calling this method in DBhelper.m file and it succesfully calling this method
-(void) loginnow:(NSString *) username andpassword:(NSString *) password
{
[self createEditableCopyOfDatabaseIfNeeded];
[self initializeDatabase];
const char *sql;
NSString *querySQL = [NSString stringWithFormat: #"SELECT username, password FROM CONTACT WHERE username='%#' AND password='%#'",username,password];
sql = [querySQL UTF8String];
if (sqlite3_prepare_v2(database, sql, -1, &init_statement, NULL) != SQLITE_OK) {
NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
while (sqlite3_step(init_statement) == SQLITE_ROW)
{
NSLog(#"char sql = %s" ,sql);
dbusername = [NSString stringWithUTF8String:(char *)sqlite3_column_text(init_statement,0)];
dbpassword = [NSString stringWithUTF8String:(char *)sqlite3_column_text(init_statement,1)];
}
if ([dbusername isEqualToString:username] && [dbpassword isEqualToString:password])
{
//DBHelper.callingViewController = self;
[self.callingViewController addview];
}
else if (dbusername != username || dbpassword != password)
{
NSLog(#"dbusername is = %#" ,dbusername);
NSLog(#"dbpassword is = %#" ,dbpassword);
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Login Failed"
message:#"Username Or Password is not Correct"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"OK ", nil];
[alert show];
[alert release];
}
sqlite3_reset(init_statement);
[self closeDatabase];
}
and also in DBhelper.h i define property for this
#property (strong) ViewController * callingViewController;
and within if condidtion in lognow method if password and username is succesully match i am calling this mathod in Viewcontroller.com file but am fail to call that
//ViewController.m
-(void) addview
{
DBHelper *f = [[DBHelper alloc] init];
f.callingViewController = self;
newview.center = CGPointMake(1000, 1000);
}
Though it's not wise to hold the viewController in the DBhelper(it breaks MVC), you could call your ViewController's method as your code but remember to set to pass your ViewController to the DBhelper. Maybe like this:
//ViewController.m
-(IBAction)login:(id)sender
{
DBHelper *objdb = [[DBHelper alloc] init];
[objdb loginnow:textname.text andpassword:textpassword.text viewController:self];
}
//DBHelper.m
-(void) loginnow:(NSString *) username andpassword:(NSString *)password viewController:(ViewController *)vc
{ ...
if ([dbusername isEqualToString:username] && [dbpassword isEqualToString:password])
{
[vc addview];
}
...
}
But in fact you should use a delegate (or block or notification, but delegate is the most case) here. Like this:
In DBHelper.h, before #interface, add
#class DBHelper;
#protocol DBHelperDelegate <NSObject>
-(void) DBHelp:(DBHelper *)helper didFinishedLoginSuc:(BOOL)suc;
#end
and between the #interface and #end tag, add(suppose you are not using ARC)
#property (nonatomic, assign) id delegate;
in the DBHelper.m, in the #implementation, add(suppose you are not using auto synthesize)
#synthesize delegate = _delegate;
Now, you can change the [self.callingViewController addview]; to
if (self.delegate && [self.delegate responseToSelector:#selector(DBHelp:didFinishedLoginSuc:)]) {
[self.delegate DBHelp:self didFinishedLoginSuc:YES];
}
Now you get a delegate prepared for every view controller which obey the DBHelperDelegate.
In your ViewController.h, tell the compiler that it obey the DBHelperDelegate by add behind the class declare:
#interface ViewController:UIViewController<DBHelperDelegate>
and change the addView method name to
-(void) DBHelp:(DBHelper *)helper didFinishedLoginSuc:(BOOL)suc
At last, when you click the button, set self as the objdb's delegate
-(IBAction)login:(id)sender
{
DBHelper *objdb = [[DBHelper alloc] init];
objdb.delegate = self;
[objdb loginnow:textname.text andpassword:textpassword.text];
}
Now, when you login successfully, -(void) DBHelp:(DBHelper *)helper didFinishedLoginSuc:(BOOL)suc in ViewController.m will be called and you can deal with your view.
Remember to set the delegate to nil when your viewController gets dealloc, or you will expect an memory error. Be careful.

Unable to navigate to home page from UIAlertView

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.

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
}
}

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.

saving NSString and then reading it back

Hey all, this should be a simple task but for some reason i am making it harder... I am trying to save some text from an XML file to a NSString. But when i debug it, the string says "Out of scope".
Here is my code:
in my .h file:
#interface RootViewController : UIViewController<MBProgressHUDDelegate> {
NSString *thePW;
}
and my .m file:
NSString *thePW;
...
- (void)viewDidLoad {
...
if(e == nil){
NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
thePW = response; // <-- this is where it has "Out of scope"
[response release];
}
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex])
{
if (thePW == #"0000")
{
NSLog(#"correct!");
}
}
}
You may also try:
thePW = [NSString stringWithFormat:#"%#",response]; // to assign the string value.
and
while comparing strings:
(thePW isEqualToString #"0000")
Drop the redeclaration of thePW in your .m file
Also, if you want to keep the value of response in thePW be sure to retain it as well.