Objective-c formatting style causes an error in a switch-case - objective-c

I'm getting an error in my switch statement with some multi-line Objective-c code:
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result
error:(NSError*)error
{
// Notifies users about errors associated with the interface
switch (result)
{
case MFMailComposeResultCancelled:
break;
case MFMailComposeResultFailed:
// NSLog(#"Mail Failed");
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"Error", #"Error")
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"OK")
otherButtonTitles:nil];
[alert show];
[alert release];
break;
default:
break;
}
}
If I uncomment the line with the NSLog, it works fine. What's causing this error? Is there any way to use this kind of formatting?

You should not declare a variable in a switch case unless you introduce a scope.
case MFMailComposeResultFailed: { // <--
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"Error", #"Error")
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"OK")
otherButtonTitles:nil];
[alert show];
[alert release];
break;
} // <--
The actual error is because in the C standard (§6.8.1), a label can only be followed by a statement (NSLog(#"Mail Failed")), not a declaration (UIAlertView* alert = ...).

The issues is with how switch is defined. You can't have a variable declaration on the line following the case. You can fix it by wrapping the entire case in a new scope
case MFMailComposeResultFailed:
{
// NSLog(#"Mail Failed");
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"Error", #"Error")
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"OK")
otherButtonTitles:nil];
[alert show];
[alert release];
break;
}

Related

Xcode 11.2.1 "Expected :" error in code segment when running build

I am using Xcode 11.2.1 and I am getting a parse error of Expected ':'.
The section of code is:
-(IBAction)webview:(id)sender {
if ([Web isEqualToString:#"Not Available"]){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"This airport does not have a Web site." message:Web delegate:self cancelButtonTitle:#"Close",nil otherButtonTitles:nil];
[alert show];
[alert release];
} else {
AirportWebViewController *web = [[AirportWebViewController alloc] initWithNibName:#"AirportWebViewController" bundle:nil];
[web setTitle:#"Selected airport"];
[web setWeb:self.Web];
[self.navigationController pushViewController:web animated:YES];
}
}
Where have I missed the placement of the ":"?
cancelButtonTitle:#"Close",nil otherButtonTitles contains an extra nil, it should be
cancelButtonTitle:#"Close" otherButtonTitles

UIAlertView Button Clicked Methods

In my email composer I would like for the result of 'cancelbuttonclicked' to close the MFMailComposerViewController. Can I implement within the switch statement or do those need to be separate methods. Also, I would like for the send button to send the message before dismissing.
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
switch (result) {
case MFMailComposeResultSent:{
UIAlertView *messageSent = [[UIAlertView alloc] initWithTitle:#"Message Sent" message:#"Your message has been sent" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[messageSent show];
break;
}
case MFMailComposeResultSaved:{
UIAlertView *messageComposeResultSaved = [[UIAlertView alloc] initWithTitle:#"Message Saved" message:#"Your message has been saved" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[messageComposeResultSaved show];
break;
}
case MFMailComposeResultCancelled:{
UIAlertView *messageComposeResultCancelled = [[UIAlertView alloc] initWithTitle:#"Message Cancelled" message:#"Your message has been cancelled" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[messageComposeResultCancelled show];
break;}
case MFMailComposeResultFailed:{
UIAlertView *messageFailed = [[UIAlertView alloc]initWithTitle:#"Message Failed" message:#"Your message could not be sent" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[messageFailed show];
break;
}
}
}
Your code should work fine. There are no limitations on using UIAlertView inside a switch. However, to make it a bit less messy, I'd suggest rewriting it like this:
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
NSString *alertTitle = nil;
NSString *alertMessage = nil;
switch (result) {
case MFMailComposeResultSent:{
alertTitle = #"Message Sent";
alertMessage = #"Your message has been sent";
break;
}
case MFMailComposeResultSaved:{
alertTitle = #"Message Saved";
alertMessage = #"Your message has been saved";
break;
}
case MFMailComposeResultCancelled:{
alertTitle = #"Message Cancelled";
alertMessage = #"Your message has been cancelled";
break;}
case MFMailComposeResultFailed:{
alertTitle = #"Message Failed";
alertMessage = #"Your message could not be sent";
break;
}
}
[[[UIAlertView alloc] initWithTitle:alertTitle
message:alertMessage
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}
It lets you avoid multiple initWithTitle....
But there is another concern: UIAlertView is deprecated is iOS 8. You should use UIAlertController instead. This answer has an example of UIAlertController usage.

multiple alert view in one view controller (tag doesn't work)

I have read some methods using alert view .tag, but that doesn't work.
The first alert:
-(void)addNewTask
{
UIAlertView * alert1 = [[UIAlertView alloc] initWithTitle:#"New Task"
message:nil
delegate:self
cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK",nil];
alert1.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert1 show];
}
The Second Alert
-(void)changeTime:(int)value atRow:(int)p
{
TaskData *data = [tasks objectAtIndex:p];
NSLog([NSString stringWithFormat:#"%d %d",data.time,value]);
int time = data.time ;
time += value;
data.time = time;
NSLog([NSString stringWithFormat:#"%d %d",data.time,value]);
[self saveData:tasks];
[self.Taskview reloadData];
if(time>=5&&(data.leveljudge!=1))
{
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:#"Congratulation!!!"
message:#"You have achieve Senior Level. "
delegate:nil
cancelButtonTitle:#"Cancel" otherButtonTitles:#"YES",nil];
data.leveljudge=1;
[alert2 show];
}
Delegate:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSString *name = [alertView buttonTitleAtIndex:buttonIndex];
if ([name isEqualToString:#"OK"])
{
UITextField *tf=[alertView textFieldAtIndex:0];
NSString *name = tf.text;
TaskData *newTask = [[TaskData alloc] init];
newTask.TaskName = name;
newTask.time = 0;
newTask.leveljudge=0;
[tasks addObject:newTask];
[self saveData:tasks];
[self.Taskview reloadData];
}
else if ([name isEqualToString:#"YES"]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://d.blog.xuite.net/d/1/5/4/12103250/blog_1606564/txt/53796893/2.jpg"]];
}
}
The problem is the delegate only work for the first alert.
My app looks like: https://www.youtube.com/watch?v=WxlVKk0CTiQ
-(IBAction)flipAction:(id)sender
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"This is My Button" message:#" Hi" delegate:self cancelButtonTitle:#"OK " otherButtonTitles:#"Cancel", nil];
alert.tag=1;
[alert show];
[alert release];
}
-(IBAction)flipAction123:(id)sender
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"This is a flipAction123" message:#"this is message..." delegate:self cancelButtonTitle:#"OK " otherButtonTitles:#"Cancel", nil];
alert.tag=2;
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
{
if (alertView.tag==1)
{
if (buttonIndex==0)
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"This is another alert button" message:#"" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
[alert show];
[alert release];
}
else
{
NSLog(#"paresh here..");
}
}
else if(alertView.tag==2)
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"This is another alert alertView.tag ==2" message:#"" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
[alert show];
[alert release];
}
}
For alert2, Delegate is not called because you have not set the delegate.
Try making the following changes.
Alert1
UIAlertView * alert1 = [[UIAlertView alloc] initWithTitle:#"New Task"
message:nil
delegate:self
cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK",nil];
alert1.alertViewStyle = UIAlertViewStylePlainTextInput;
alert1.tag = 101; //Add a Tag to the alert
[alert1 show];
Alert2
Alert 2 delegate is not set properly
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:#"Congratulation!!!"
message:#"You have achieve Senior Level. "
delegate:self //Set your delegate
cancelButtonTitle:#"Cancel" otherButtonTitles:#"YES",nil];
alert2.tag = 102; //Add a different tag value to the second alert
data.leveljudge=1;
[alert2 show];
Delegate
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(alertView.tag == 101)
{
//Handle Alert 1
}
else if(alertView.tag ==102)
{
//Handle Alert 2
}
}
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:#"Congratulation!!!"
message:#"You have achieve Senior Level. "
delegate:self //here should be self, not nil
cancelButtonTitle:#"Cancel" otherButtonTitles:#"YES",nil];
data.leveljudge=1;
[alert2 show];

Objective C dismissViewControllerAnimated move last view down

I have two ViewController
VC1 adding VC2 as an subview to itselfe.
VC2 has a UIButton, which is calling the follow Code:
if([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:[NSString stringWithFormat:#"BlaBla."]];
NSArray *toRecipients = [NSArray arrayWithObjects:#"blabla#gmail.com", nil];
[mailer setToRecipients:toRecipients];
NSString *emailBody = [NSString stringWithFormat:#"Testtext1"];
[mailer setMessageBody:emailBody isHTML:NO];
[self presentViewController:mailer animated:YES completion:nil];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Fehler" message:#"Ihr Gerät unterstützt die gewünschte Funktion nicht" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
}
After the Mail is done it calls the following:
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{
switch (result)
{
case MFMailComposeResultCancelled:
{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hinweis"
message:#"Vorgang abgebrochen, es wurde keine E-Mail versendet."
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
}
break;
case MFMailComposeResultSaved:
{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hinweis"
message:#"Ihre E-Mail wurde gespeichert."
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
}
break;
case MFMailComposeResultSent:
{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hinweis"
message:#"Ihre E-Mail wird versendet."
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
}
break;
case MFMailComposeResultFailed:
{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hinweis"
message:#"Vorgang abgebrochen, die E-Mail konnte nicht gesendet werden."
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
}
break;
default:
{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hinweis"
message:#"E-Mail wurde nicht gesendet."
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
}
break;
}
[self dismissViewControllerAnimated:YES completion:nil];}
All works fine, but all UIButtons etc in VC2 are now moved, I guess, 20 pixels down.
I cant Imagin why, I guess the problem is I adding a ViewController as Subview to an other ViewController and calling there the methode. But I cant imagin how to solve the issue.
I had similar problem but parent view was moved 20 px up.
Solution was based on changing "Wants full screen". I had to set this values to YES but not to all child view controllers.

How can I make it so only 1 "if-statement" is used if 2 are in the action

In a game...
When the "done" button is pressed, there are 2 'if-statements': one brings you to the next level and the other returns you home. How can I make it so only one happens at a time? The way it works now, is both the winning and losing 'alertviews' pop up no matter if the user got it right or wrong. This is how it looks:
-(IBAction)done {
if ([entry.text isEqualToString:sentance.text]) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Cleared!"
message:#""
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
[alert release];
seconds.text = #"5 Seconds";
}
if ([entry.text isEqualToString:entry.text]) {
NSString *nssScore= [NSString stringWithFormat:#"Final Score: \n %i Points", Score];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Nope! Wrong"
message:nssScore
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
[alert release];
}
}
There is something wrong with your second if.
if ([entry.text isEqualToString:entry.text]) {
This if is always true, since why should entry.text not be equal to itself?
Also if you have two if statements and only one shall be true, you always use a else if for the second one:
if (<condition>) {
} else if (<other condition>) {
}
If condition is true, the other if is not executed, even if other condition is also true. However, in your case your second if seems nonsense to me. An if that is always true is useless and be left out completely. The code is equivalent to
if (<condition>) {
} else {
}
You can use else if condition.
Like this :
-(IBAction)done {
if ([entry.text isEqualToString:sentance.text]) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Cleared!"
message:#""
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
[alert release];
seconds.text = #"5 Seconds";
}
else if ([entry.text isEqualToString:entry.text]) {
NSString *nssScore= [NSString stringWithFormat:#"Final Score: \n %i Points", Score];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Nope! Wrong"
message:nssScore
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
[alert release];
}
}
or you can add a line of code in each block "return;"
like this:
I got the answer guys...
if ([a.text isEqualToString:b.text] == FALSE) {
condition
}
Thanks!