UIAlertView crash iOS7 - Assertion failure - uikit

I have a problem regarding the UIAlertView on iOS7.
When I launch my application, it crashes with the following message:
*** Assertion failure in -[UIKeyboardTaskQueue performTask:], /SourceCache/UIKit_Sim/UIKit-2903.2/Keyboard/UIKeyboardTaskQueue.m:388
The error occurs on the following line:
- (IBAction)updatePositions:(id)sender{
_alert = [[UIAlertView alloc] initWithTitle:#"text" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
[_alert show]; <====== IT CRASHS HERE
[NSThread detachNewThreadSelector:#selector(updateDataThread) toTarget:self withObject:nil];
}
I'm using ARC and the property _alert is set defined as: #property (nonatomic,strong)
This error seems strange, because on iOS6 the code works perfectly and I don't know what should be different on iOS7.
Does anyone have an idea what could the error?
Thanks in advance.

I encountered the same error, and the issue was that the UIAlertView was attempting to be shown from a thread which wasn't the main thread.
The crash however wouldn't always occur, only when a first AlertView was already being shown while this second AlertView was trying to pop up as well.
In my case, a simple fix was to do:
//Your code here
...
//Alert
_alert = [[UIAlertView alloc] initWithTitle:#"text" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
dispatch_async(dispatch_get_main_queue(), ^{
//Show alert here
[_alert show];
});
//Resume your code here
...

I just had this problem after forgetting that I was working from a background thread. I don't know if that's the case here, but I'd make sure you're not trying to call updatePositions: from anything other than the main thread.

Change your code like this :
_alert = [[UIAlertView alloc] initWithTitle:#"text" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
[_alert show];
removing [[ and ]] around #"text"
But, your I don't think your problem came from this UIAlertView.

I had the same problem as well but not too familiar with the method dispatch_async. I used
[alert performSelectorOnMainThread:#selector(show) withObject:nil waitUntilDone:NO];
and the problem hasn't come up again.

Put your alertview code in a separate function like
-(void)showAlert
{
_alert = [[UIAlertView alloc] initWithTitle:#"text" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
[_alert show];
}
Then in your IBAction do this
- (IBAction)updatePositions:(id)sender
{
[self performSelectorOnMainThread:#selector(showAlert) withObject:nil waitUntilDone:YES];
[NSThread detachNewThreadSelector:#selector(updateDataThread) toTarget:self withObject:nil];
}

You can also do like this:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Your title" message:#"Your message" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert performSelectorOnMainThread:#selector(show) withObject:nil waitUntilDone:YES];
However, if you need to show the same alert in multiple places it's better to create a separate function for it.

Related

Alertview for textfiled works on ios7 but not working on ios6.1

if ([district.text isEqualToString:#""])
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Alert" message:#"Please fill the fields" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
else if([myTextField.text isEqualToString:#""])
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Alert" message:#"Please fill the fields" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
else if ([catname.text isEqualToString:#""])
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Alert" message:#"Please fill the fields" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
else if([msg.text isEqualToString:#""])
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Alert" message:#"Please fill the fields" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
This is my code it works perfectly in ios7 but not in ios6. what changes should I make to work it on ios 6.1
You can't easily alter the view hierarchy of a UIAlertView in iOS 7. (Nor should you; the documentation specifically tells you not to.) Head over to the developer forums to see a long discussion about it.
One alternative in your case is to set alert.alertViewStyle = UIAlertViewStylePlainTextInput; This will add a text field for you. You can access it in the UIAlertView delegate callback by using UITextField *textField = [alertView textFieldAtIndex:0];.
Example:
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Alert"
message:#"enter your details:"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok", nil];
[alertView setAlertViewStyle:UIAlertViewStylePlainTextInput];
/* Display a numerical keypad for this text field */
UITextField *textField = [alertView textFieldAtIndex:0];
textField.keyboardType = UIKeyboardTypeNumberPad;
[alertView show];

How to assing a custom method inside a #selector XCode5

I have a NSAlert in XCode5
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:#"Notificación"];
[alert setInformativeText:mensaje];
[alert setAlertStyle:NSInformationalAlertStyle];
[alert beginSheetModalForWindow:window modalDelegate:nil
didEndSelector:#selector(myMethod})
contextInfo:nil];
as you see on didEndSelector I have a section for adding a method, is it possible to create there inside a custom method for making just an action, for instance something like this
[alert beginSheetModalForWindow:window modalDelegate:nil
didEndSelector:#selector(myCustomMethod{NSLog(#"hola");})
contextInfo:nil];
this is for saving the time of adding tons of methods one for each NSAlert
thanks in advance for the support
create separated method with some NSLOG for example
- (void)logs {
NSLog(#"lalalalalal")
}
Then send it to selector:
#selector(logs)
If your method receiving some variable, your select should be like:
#selector(logs:)

Pop-up message on macOS programming

Like using UIAlertView on iOS. There should be a similar solution for creating a pop-up message on macOS. Tried to search but could not find anything useful.
The class you're looking for is NSAlert. Information on this class can be found in its class reference here. And here is an example of its usage:
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:#"Some awesome message text"];
[alert addButtonWithTitle:#"OK"];
[alert runModal];

Alerts and if statements - Xcode

I'm trying to trigger an alert with an if statement. but the code im using wont do what i want.
This is one attempt at triggering the alert
-(Void)ShowAlert
if (mainInt == 120) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Title" message:#"Message"
delegate:nil cancelButtonTitle:#"Dismiss"otherButtonTitles:nil, nil];
[alert show];
}
i have declared 'ShowAlert' in the .h file as -(void)ShowAlert just under my -(IBAction) declares.
But still no alert when ran in simulator. Any help with this would be greatly appreciated!!
THANKS
(I'm am using Xcode 4.6.2)
Maybe if (mainInt == 120) is never true.
I would try with an ELSE if i were you. And log whole process about what's going on like this:
-(void)ShowAlert{
if (mainInt == 120){
NSLog(#"TRUE i should see the alertview! , mainInt = %i",mainInt);
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Title" message:#"Message"
delegate:nil cancelButtonTitle:#"Dismiss"otherButtonTitles:nil, nil];
[alert show];
}else{
NSLog(#"FALSE , mainInt = %i",mainInt);
}
}

Two different MFMailComposeViewController same view

hi i Have Two different MFMailComposeViewController same view, they write at two different mail address, i need to set one different success alert each one. I try with tag but MFMailComposeViewController can't use tag?
how i can do that?
That's my second MFMailComposeViewController
-(IBAction)inviaMail2{
MFMailComposeViewController *mail2 = [[MFMailComposeViewController alloc] init];
mail2.mailComposeDelegate = self;
if([MFMailComposeViewController canSendMail]){
[mail2 setToRecipients:[NSArray arrayWithObjects:#"piccolericette#alternativeindustries.it", nil]];
[self presentModalViewController:mail2 animated:YES];
}
[mail2 release];
}
- (void)mailComposeController2:(MFMailComposeViewController *)controller2 didFinishWithResult:(MFMailComposeResult)result2 error:(NSError *)error{
[self dismissModalViewControllerAnimated:YES];
if (result2 == MFMailComposeResultFailed){
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:#"Messaggio non inviato." message:#"Non è stato possibile inviare la tua mail, verifica la tua connessione internet e riprova." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
}
else {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:#"Messaggio inviato." message:#"Grazie per avermi contattato, ti risponderò il più presto possibile." delegate:self cancelButtonTitle:#"Prego" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
}
}
Update:
I somehow missed that you can access controller.view.tag which is closer to what OP wanted.
I'll keep my generic answer since it may apply to other situations where you don't have a custom field you can use.
Original Answer:
This is more of a generic design solution (workaround?) to this problem.
I'm not sure if MFMailComposeViewController has any dynamic user-info field you can use to differentiate, but you can define 2 MFMailComposeViewController* properties in your class, assign to them when creating, and check against them on result.
Something like:
#property (...) MFMailComposeViewController *mail1;
#property (...) MFMailComposeViewController *mail2;
self.mail1 = [[MFMailComposeViewController alloc] init];
...
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result2 error:(NSError *)error{
if(controller == self.mail1) { ... }
}

Resources