The App I’m trying to do has a tabbar controller.
When the App starts, I’m getting the user location in the AppDelegate and when I’ve got the accuracy I need the AppDelegate sends an NSNotification to my App’s starting page (index 0 of the tab bar controller).
Upon receiving the notification, this view tries to send an email with the user coordinates and other data, but as soon as the MFMailComposeViewController is presented I get the following error:
Warning: Attempt to present <MFMailComposeViewController: 0x98a0270> on <UITabBarController: 0x988c630> whose view is not in the window hierarchy!
What am I missing?
Thanks.
EDIT: adding some code…
This is what I’ve got in my AppDelegate.m:
- (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSUserDefaults *phoneNumbers = [NSUserDefaults standardUserDefaults];
NSDate *eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 10.0) {
[self locationUpdate:newLocation];
smsLoc = newLocation;
if ([[phoneNumbers objectForKey:@"sendSMS"] isEqualToString:@"yes"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"sendSMS" object:nil];
} else if ([[phoneNumbers objectForKey:@"sendEmail"] isEqualToString:@"yes"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"sendEmail" object:nil];
}
}
}
Then, in my first view controller I have:
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendSMS:) name:@"sendSMS" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendEmail:) name:@"sendEmail" object:nil];
}
And at the end, the selector for “sendSMS” (the other is pretty similar):
- (void)sendSMS: (NSNotification *)notification {
NSUserDefaults *phoneNumbers = [NSUserDefaults standardUserDefaults];
if ([phoneNumbers objectForKey:@"first"] || [phoneNumbers objectForKey:@"second"]) {
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if ([MFMessageComposeViewController canSendText]) {
AppDelegate *deleg = (AppDelegate *)[[UIApplication sharedApplication] delegate];
controller.body = [NSString stringWithFormat:@"some message with coordinates %.4f - %.4f", [deleg currentLocation].coordinate.latitude, [deleg currentLocation].coordinate.longitude];
controller.recipients = [NSArray arrayWithObjects:[phoneNumbers objectForKey:@"first"], [phoneNumbers objectForKey:@"second"], nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
}
}
}
}
Second edit: adding some more code.
UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.delegate = self;
tabBarController.selectedIndex = 0;
[[tabBarController.tabBar.items objectAtIndex:0] setTitle:NSLocalizedString(@"Home", nil)];
[[tabBarController.tabBar.items objectAtIndex:1] setTitle:NSLocalizedString(@"Requests", nil)];
[[tabBarController.tabBar.items objectAtIndex:2] setTitle:NSLocalizedString(@"Account", nil)];
[[tabBarController.tabBar.items objectAtIndex:3] setTitle:NSLocalizedString(@"Settings", nil)];
//some other controls from DB
[[tabBarController.tabBar.items objectAtIndex:1] setBadgeValue:[NSString stringWithFormat:@"%d",number]];
The tabbarController has been made via IB, but I’ve added the code above in my AppDelegate because I need to localize the tab bar items and to add a badge to one of them.
Am I doing something wrong here?
I’m not sure if you have solve this issue. The error message means the viewcontroller you use to present another modal viewcontroller is not visible on the window. This can happen for e.g:
If your issue is like above, you can fix it like:
If that doesn’t fix your issue, maybe you can try to present using self.tabBarController instead of self. Again just suggestion, not sure if it works though.