Application tried to push a nil view controller on target <MFMessageComposeViewController: 0x96d1380> - objective-c

Has anybody encountered this kind of error in MFMessageComposeViewController?
I allocated and presented it like this:
MFMessageComposeViewController *message = [[MFMessageComposeViewController alloc] init];
message.messageComposeDelegate = self;
[[UIApplication sharedApplication].delegate.window.rootViewController presentModalViewController:message animated:YES];
but it presents an empty view and says:
Application tried to push a nil view controller on target <MFMessageComposeViewController: 0x96d1380>.

Possible duplicate of MFMessageComposeViewController on Simulator - canSendText?
Basically this occurs in the simulator on Lion and Mountain Lion if it has a Messages account enabled. Try testing on a real device as it should work okay there.

Related

ios 8 : ABPeoplePickerNavigationController dismiss on implementing people picker delegate methods

This is strange behavior noticed while accessing contact details from address book in ios 8.
My scenario is simple
Show contacts table
select a row that will invoke didSelectPerson method
in didSelectPerson method
push SecondViewController
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person;
{
SecondViewController *detailVC = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[detailVC.view setBackgroundColor: [UIColor redColor]];
// [peoplePicker.navigationController pushViewController:detailVC animated:YES];
[peoplePicker pushViewController:detailVC animated:YES];
}
but what happens is ABPeoplePickerNavigationController dismiss.
Please enlighten me on this.
I don't know the philosophy thing what happens under the hood of the "didSelectPerson" method, me was facing the same problem today. I found a simple solution to overcome this issue, i override the
"-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion" method of the "ABPeoplePickerNavigationController". Then implement it like somewhat following
bool dismissedEnabled;
-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
{
if (dismissedEnabled) {
[super dismissViewControllerAnimated:flag completion:completion];
}
}
then inside the "didSelectPerson" i have done the following
viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:[NSBundle mainBundle]];
dismissedEnabled = false;
[self presentViewController:viewController animated:YES completion:nil];
this works for me, hope you guys overcome it too :)
It automatically dismisses if you select a contact with a single email address for example.
If a contact has more than one email, you must specify a predicate that will force the ABPeoplePickerNavigationController to push a ABPersonViewController on the stack.
if ([picker respondsToSelector:#selector(setPredicateForSelectionOfPerson:)])
{
// The people picker will select a person that has exactly one email address and call peoplePickerNavigationController:didSelectPerson:,
// otherwise the people picker will present an ABPersonViewController for the user to pick one of the email addresses.
picker.predicateForSelectionOfPerson = [NSPredicate predicateWithFormat:#"emailAddresses.#count = 1"];
}
I believe the default behavior in iOS 8 is that the ABPeoplePickerNavigationController is automatically dismissed when didSelectPerson is called.
The reason that the SecondViewController is not displayed (I'm inferring that this is the problem symptom) is because you are trying to push the SecondViewController while the ABPeoplePickerNavigationController is being dismissed. This overlapping animation is a problem that the iOS core view management/animation system tries to avoid.
You may get a warning in the console when this happens.
#Ratul's solution works because it circumvents this default behavior.
In my scenario, my code sleeps a second before presenting a UIAlertController from within didSelectPerson. This is a hack that depends on the ABPeoplePickerNavigationController dismissal animation taking less than a second. For me, if this alert is not displayed, nobody would even notice this was a problem.
If you want something more robust, you may want to override viewDidAppear to handle this special case (using a flag in your presenting view controller). But this gets a bit clumsy as well.

iOS7 sending SMS from inside the app has a misaligned modal view

I'm writing an app where I need to allow the user sending SMS from within the app.
It works fine on iOS6 but not on iOS7.
When I'm trying to send a text message, the modal view appears but there is a strange gap between the "to" field and the list of possible contacts.
After selecting the first contact, the "to" field slides up and disappears and then I see past messages and my new message but with the same gap again.
I'm attaching two images showing the issue:
Here is the code I'm using:
if([MFMessageComposeViewController canSendText]) {
NSArray *recipents = nil;
NSString *message = #"Let's go";
MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
messageController.messageComposeDelegate = self;
[messageController setRecipients:recipents];
[messageController setBody:message];
[self presentModalViewController:messageController animated:YES];
}
Please tell me if know you know how to fix this issue.
Thanks!
Additional info:
This bug only happens in iOS 7.x not in in iOS 6.x
Also, if I use the MFMailComposeViewControllerDelegate to send emails, it works just fine (although they are both implemented by MessageUI.h)...
Ok, I figured it out.
The issue happens because I have a custom UINavigationController.
In my AppDelegate, I had the following code:
UIImage *navBarImage = [UIImage imageNamed:#"BarIos7.png"];
[[UINavigationBar appearance] setBackgroundImage:navBarImage forBarMetrics:UIBarMetricsDefault];
Once I removed it, everything started working fine.

Application used MapKit crash on iOS6

I have a strange problem with google map in my application dedicated for iPad (with iOS6). I've made a horizontal scroll view, filled with two views. One is a detail information view (some text, nothing special), and the second view is a view controller with google map. This is the universal scheme in my application (scrollview build from two views) for a few different purposes. The problem occurs when I've started to test the app on a real iPad with iOS6. The application crash when it should view a scroll view. But not immediatly. At start, scroll view is viewed properly. Then I want to build a new scroll view with new datas. It also goes fine, and scroll view is viewed properly. After a few operation like that I've start to receiveing more and more error logs like this:
failed to make complete framebuffer object 8cdd
After a few runs of scrollView, the application crash without any additional errors. Code editor points on main.m file, and the following line:
int retVal = UIApplicationMain(argc, argv, nil, nil);
Please direct me to find what am I doing wrong. Where is the viewDidLoad method from my view controller responsible for viewing the google map:
-(void)viewDidLoad {
mapView.mapType = MKMapTypeSatellite;
mapView.showsUserLocation = YES;
/* ANNOTATION (pin) */
CLLocationCoordinate2D annotationCoord;
annotationCoord.latitude = [self.restaurant.latitude doubleValue];
annotationCoord.longitude = [self.restaurant.longitude doubleValue];
// a pin with the info.
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
annotationPoint.coordinate = annotationCoord;
annotationPoint.title = self.restaurant.name;
// add annotation to the map
[mapView performSelectorOnMainThread:#selector(addAnnotation:)
withObject:annotationPoint
waitUntilDone:YES];
[annotationPoint release];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance (annotationCoord, 500, 500);
[self.mapView setRegion:region animated:YES];
[super viewDidLoad];
}
and no mater how I push the view controller with google map to the view. It always crash my app :(. I`ve tried like this:
[scrollView addSubview:self.googleMapViewController.view];
or that:
[[self navigationController] pushViewController:self.googleMapViewController animated:YES];
When I run the application on simulator, there`s everything all right. I'm using XCode 4.5.1.
I had the same problem in one of my projects. It was caused by a memory leak. Map views consume alot of memory if you don't delete them. It doesn't appear on simulator because a computer can use much more memory.
Just make sure to get rid of the map views when you no longer need them.
I also recommend running the app with Instruments (Leaks) - it is an extremely useful tool in such cases.

UIDocumentInteractionController: "Open In" visible on iPhone but not on iPad - why?

For testing purposes I wrote two apps:
First one plays an MP3 file using UIDocumentInteractionController
Second one does nothing but registers for the file type "public.mp3"
If I deploy the apps to the iPhone Simulator, my MP3 player app shows a button on top "Open in 'MP3Test'". If I deploy to the iPad Simulator however, there is no button and no "Open In" menu either.
This has been tested with iOS5.
Can somebody explain if this is a bug or a feature and what the reason is behind it?
Depends upon where you are presenting it from.
If you are presenting it from somewhere around the middle of the screen or below, just present from the frame of the object that you are presenting from.
if that is on the navigation bar, try this:
NSString *fileToOpen = [[NSBundle mainBundle] pathForResource:#"License" ofType:#"pdf"];
UIDocumentInteractionController *controller = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileToOpen]];
controller.delegate = self;
CGRect navRect = self.navigationController.navigationBar.frame;
navRect.size = CGSizeMake(1500.0f, 40.0f);
[controller presentOptionsMenuFromRect:navRect inView:self.view animated:YES];
The iPad has an affinity for popovers (see UIPopover), why it presents UIActionSheets in them. Facing a similar issue that you had, I had my UIDocumentInteractionController present itself from an UIBarButtonItem (resulting in a UIPopover presentation), rather than from the view itself (something that worked just fine on the iPhone):
Save a reference to the action button (I have mine in my navigation bar).
Use PresentOpenInMenu using the action button reference, rather than the View reference, resulting in a UIPopover-presentation.
Please note that the change does not effect the iPhone app - it behaves likes before, i.e. opens the OpenInMenu from the bottom of the screen just as it would, if you'd used the View reference to present it.
On iPad UIDocumentInteractionController appearing like Pop Up Try something like this
-(void)shareClick:(UIButton*)sender {
/*some code*/
CGRect rectFor appearing = [sender.superview convertRect:sender.frame toView:self.view];
[interactionController presentOptionsMenuFromRect:rect inView:self.view animated:YES];
}

How does conditionally coding for iPhone and iPad work in reality?

UIImagePicker must be presented differently on iPhone and iPad. On the iPad, it throws an exception saying this:
* Terminating app due to uncaught exception
'NSInvalidArgumentException', reason:
'On iPad, UIImagePickerController must
be presented via UIPopoverController'
So I must add code to my universal app which is iPad specific. What is a safe way to do it so that the app won't crash on devices which lack a UIPopoverController?
Example:
popover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
[popover presentPopoverFromRect:CGRectMake(100, 100.0, 0.0, 0.0)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
Also, in case I need a UIPopoverController, I need an instance variable that holds it. How would I handle this?
You can check to see if a class exists by doing this.
Class popoverClass = (NSClassFromString(#"UIPopoverController"));
if (popoverClass != nil) {
// you're on ipad
} else {
// you're on iphone/ipod touch
}
This question looks like a dup of:
Is there a specific Xcode compiler flag that gets set when compiling for iPad?
You can do a quick check of which device you are on with:
[[UIDevice currentDevice] model];