GameCenter authentication in landscape-only app throws UIApplicationInvalidInterfaceOrientation - ios

Problem:
If user is not logged into GameCenter account - GameCenter authentication view is launched in portrait mode (in ios 5 there were a modal dialog) asking to log in. But if I disable Portrait mode in xcode (Project Summary) or in supportedInterfaceOrientationsForWindow: (as my app supposed to run in landscape mode ONLY) I get:
Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES'
If I enable Portrait for ipad/iphone (and/or comment out supportedInterfaceOrientationsForWindow:) it works without crash, but I don't want portrait mode to be enabled.

While writing this question and experimenting with code, it seems that I've found a solution:
enable all orientations in project summary and remove application:supportedInterfaceOrientationsForWindow.
Add this code to ViewController:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
Now it works seamlessly.

Add to app delegate:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)w {
return (NSUInteger)[application supportedInterfaceOrientationsForWindow:w] | (1<<UIInterfaceOrientationPortrait);
}

I have found that the problem is coming from the Game Center in my case. When in the simulator I do not have the Game Center initialized yet, it would like to pop up the login view, but in portrait mode. Once it is reaching this point it crashes if I disallowed portrait orientation. Strange bug in the OS as Game Center should take the allowed orientations only to be inline with our intention of landscape user interface.
I do not have the solution yet, but I will post if I find it.

I had the same issue as you and I fixed it with a kinda, ugly work around, basically I have a global variable in my app that I use to choose what the valid interface orientations are. In the
- (NSInteger)application : (UIApplication *)supportedInterfaceOrientationsForWindow:(UIWindow *)window{
if(orientationIndicator == 1){
return UIInterfaceOrientationMaskAllButUpsideDown;
}
else if(orientationIndicator == 2){
return UIInterfaceOrientationMaskLandscape;
}
}
To declare the global variable put this in your appDelegate.m file :
int orientationIndicator = 1;
To import the global variable use :
extern int orientationIndicator;
Then you can change the value of orientation indicator and it will allow you to run in different interface types. So what I did was I start by making the orientationIndicator = 1. When you authenticate a player and initiate the login view controller set the orientation indicator to 2. When you dismiss the view (authenticate the player) then you can change it back to 1.
This is a slimy work around but it has worked for me.
Hope this helps!

Catching the exception appears to work just fine for me:
#try {
[rootNavigationController pushViewController:viewController animated:YES];
}
#catch (NSException *exception) {
//somehow, catching this exception just allows the view controller to be shown?
}
In iOS 6.0, the exception is thrown, but if you catch it then the viewController will still be shown and GameCenter will behave as expected in landscape orientation.
An alternate solution is just to target iOS 6.1 and above, as Apple fixed the bug by that release.

Related

iOS: crash if sharing with "Message" option

Our app only supports portrait mode. Presenting a UIActivityViewController works.
However, sharing with the "Message" option crashes the app:
*** Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'Supported
orientations has no common orientation with the application, and
[MFMessageComposeViewController shouldAutorotate] is returning YES'
Sharing with another option, such as Facebook Messenger, works.
Solutions from similar SO questions like this one do not work since they suggest supporting all orientations. We only want to support portrait.
1) How can we support the "Message" share option while only supporting portrait orientation, that is while only supporting portrait orientation in Info.plist?
2) Why are we able to support the "Message" share option in other apps with only portrait orientation in Info.plist but not this one? Where should we look for debugging purposes?
// Define share objects
let objectsToShare = ["test message"] as [Any]
// Configure UIActivityViewController
let activityViewController = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityViewController.excludedActivityTypes =
[UIActivityType.addToReadingList,
UIActivityType.assignToContact,
UIActivityType.print,
UIActivityType.copyToPasteboard]
// Define completion handler
activityViewController.completionWithItemsHandler = doneSharingHandler
// Show UIActivityViewController
present(activityViewController, animated: true, completion: nil)
I tried for a while to reproduce this bug and could not get it to crash. Finally I was able to get this exact crash when I returned UIInterfaceOrientationPortrait when I should have been returning UIInterfaceOrientationMaskPortrait for one of the orientation functions. Check your view controller's implementation of supportedInterfaceOrientations and your implementation of application:supportedInterfaceOrientationsForWindow:
Here is a very hackish solution that should work for an app that only presents in portrait.
Create a category over MFMessageComposeViewController and override supportedInterfaceOrientations and shouldAutorotate to only support portrait.
You may need to create this category in Objective C to actually get it to compile, but it will work.
#interface MFMessageComposeViewController (NoRotation) #end
#implementation MFMessageComposeViewController (NoRotation)
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate {
return NO;
}
All of your individual view controllers can support only portrait, by implementing supportedInterfaceOrientations to return UIInterfaceOrientationPortrait.
But your app, meaning the Info.plist or the app delegate's application(_:supportedInterfaceOrientationsFor:), should support all orientations.
This will allow the runtime to present this MFMessageComposeViewController the way it wants to, but all of your view controller will still be in portrait only, which is what you want.
Stray code (bad developer, bad developer, bad developer!) elsewhere in the app caused the bug.
An extension of UINavigationController elsewhere in the code overrode supportedInterfaceOrientations and caused everyone here to waste time over a stupid bug. Sorry! Hopefully our sloppiness benefits some future user, though.
Removing the extension fixed the bug.
If SO ever decides to recognize and award the worst developers around, we're happy to stand for nomination. :)

Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES' in xamarin iOS

My app supports only landscape mode. when i am trying to open image picker within the app it shows an exception which is as follows:
"Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES"
I had tried to make false value for shouldAutorotate but didn't succeed. I am stuck with this. Any one have any help regarding this?
If you like to use UIImagePickerController as lanndscape mode , instead of
- (BOOL)shouldAutorotate
{
return NO;
}
use this
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
but make sure to check this as:

How to create a landscape-view only ios application

I want to create an iOS app that can only work on landscape-view mode.
I Googled how to do that, and end up with supportedInterfaceOrientations method
Here's my attempt:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
}
I tried to put the above code on viewController.m and AppDelegate.m, but it didn't seem to work
Thanks, any opinion will be much appreciated
You don't need to write any code to run app which supports landscape mode only. Just select app target and uncheck portrait and portrait upside down orientation and make sure landscape orientation is checked.
It seems as though you want to programmatically change the orientation of your application. This can be done by any ViewController by implementing one method.
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
That should force the view to auto-rotate in the direction you want it.
When you use -supportedInterfaceOrientationForPresentation it simply states that the returned interfaces can be used, not necessarily that they should be used.
When you use -preferredInterfaceOrientationForPresentation it says that this is orientation that I want, and that the ViewController should switch to it.

Everyplay records video, but crashes when i tap on "Share" and "View profile"

I am using everyplay to record my game play, and players can share the video at the result screen.
The recording, sharing and viewing of profile on the iPad is working fine, but every iPhone build (4, 4S, 5) will crash when I tap on the "share", "view everyplay profile" button at the Everyplay page.
We tracked what is happening when we tapped on those 2 buttons.
2013-08-01 10:29:19.489 ZombieBlackout[6602:907] Video Updated
2013-08-01 10:29:20.786 ZombieBlackout[6602:907] everyplayRecordingStopped
2013-08-01 10:29:20.788 ZombieBlackout[6602:907] everyplayShown
2013-08-01 10:29:22.393 ZombieBlackout[6602:907] Audio route change while recording was stopped.
2013-08-01 10:29:22.394 ZombieBlackout[6602:907] A route change occurred that does not require stopping application audio.
2013-08-01 10:29:22.451 ZombieBlackout[6602:907] Audio route change while recording was stopped.
2013-08-01 10:29:22.453 ZombieBlackout[6602:907] A route change occurred that does not require stopping application audio.
2013-08-01 10:29:27.488 ZombieBlackout[6602:907] Video Updated
2013-08-01 10:29:35.383 ZombieBlackout[6602:907] *** Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES'
*** First throw call stack:
(0x3304f3e7 0x3ad40963 0x3304f307 0x34ec688f 0x3506b0c9 0x3f388d 0x3f0dad 0x3e1e5b 0x3e1d4b 0x3b15a793 0x3b15a5db 0x3b15de45 0x330231b1 0x32f9623d 0x32f960c9 0x36b7433b 0x34eb22b9 0xb1503 0xb02b8)
libc++abi.dylib: terminate called throwing an exception
And I don't think it is because our build is on the iPhone, because I tried Nimble Quest on iPhone and I am able to tap on the stated 2 buttons.
I am using Cocos2dx, the way we code is ready for Android. I am wondering if there is a problem with cocos2dx with Everyplay.
Please advise.
Thanks
I assume your game is landscape only. In that case you have two options how to fix this.
Option 1:
Add UISupportedInterfaceOrientations array into your game's info.plist with items UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight and UIInterfaceOrientationPortraitUpsideDown. You can easily do this from xCode by checking all Supported Interface Orientations from your project summary page or by editing the info.plist file manually.
Option 2:
Add the following method to your application's AppDelegate.m file:
// IOS 6
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskAll;
}
In both cases you must also make sure that you have added the landscape only orientation handling code to your game's UIViewController.
// IOS 5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
// IOS 6
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

different UIViewController Orientations depending on which view the user is in

I would like to set different rules for the different viewControllers in my apps, not a single rule across all views (like you can define in Target-Summary).
For instance I have several views I would like my first few views to only appear in portrait view, however in my last view I would like the user to be able to change between protrait and landscape... I was woundering how I could do this.
Also I have read issues where the user navigates to a view while in landscape and the view appears landscape when it should be portrait and will not change untill the user rotates the device, I would like to avoid this if possible...
So my question is how can I allow different UIViewController Orientations depending on which view the user is in.
This will depend on whether you target iOS 5 or iOS 6.
iOS 5:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
if ((orientation == UIInterfaceOrientationPortrait) ||
(orientation == UIInterfaceOrientationLandscapeLeft))
return YES;
return NO;
}
iOS 6:
Set your default supported orientations in the App Summary and then in VC's you want to be different:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
}
Apple Documentation for this HERE
See these questions for more info:
shouldAutorotateToInterfaceOrientation not being called in iOS 6
shouldAutorotateToInterfaceOrientation is not working in iOS 6

Resources