4

I am working on an app for a client that runs in the background.

It's not an app store app, so it does not have quite the same rules that normally apply to app store apps. Even private APIs are an option for this app, but it must run on a non-jailbroken device. (The app will be an enterprise app.)

The app needs to know the current device orientation. Seems simple, but it's not. I'm using the normal code you'd expect:

UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
BOOL inLandscape = UIDeviceOrientationIsLandscape(deviceOrientation);

However, it seems that this returns the orientation that was in force when the app moved from foreground to background.

I need the orientation to track the actual device orientation. Actually what I REALLY want is the user interface orientation of the current foreground app, but Apple makes that really hard to deduce. I'll settle for the device orientation if I have to.

This app is written in Objective-C, but I "speak Swift" as well, so answers expressed in either language are fine.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Just spitballing here: there's a few frameworks with [private `deviceOrientation` properties](https://github.com/nst/iOS-Runtime-Headers/search?utf8=%E2%9C%93&q=deviceorientation), a private `UIDevice` method called `currentDeviceOrientationAllowingAmbiguous:`, and of course `[UIApplication -statusBarOrientation]`. Have you tried any of those out? – Aaron Brager Sep 15 '15 at 15:02
  • [Here's an approach](http://codrspace.com/yuvirajsinh/device-orientation-detection-using-coremotion/) that uses Core Motion's `CMMotionManager` to calculate the device orientation. – Aaron Brager Sep 15 '15 at 15:05
  • Do you need to literally "track" the orientation, as in to maintain a record of all the changes while your app is backgrounded? Or do you just need to know the orientation when the app returns from the background? In case of the latter, you could just check device orientation in `applicationWillEnterForeground:` in the AppDelegate. – William Smith Sep 15 '15 at 15:06
  • What I really need is the user interface orientation of the front app. Using core motion might be a decent compromise, but it gets out of sync with the UI orientation if device is orientation locked, or if the user has it flat on a table, or various other cases. – Duncan C Sep 15 '15 at 15:22
  • A private framework that lets me interrogate the user interface of the frontmost app (or it's status bar orientation) would be ideal. – Duncan C Sep 15 '15 at 15:23
  • Keep in mind that, even if you don't publish your app to the app store, private APIs are by nature subject to change without prior notice in future versions of iOS; your app might break down the road and then you will have to fix it. – Nicolas Miari Sep 15 '15 at 22:25
  • Understood. That's the big reason for not using them. They aren't part of Apple's "contract", and they are under no obligation to support those calls in a future version. It's the cost of reaching under the public API. – Duncan C Sep 15 '15 at 23:06

2 Answers2

6

There is a private method called -[UIApplication _getSpringBoardOrientation] which just calls another private method -[UIApplication activeInterfaceOrientation], which seems to give you the orientation of the current foreground app.

Sascha
  • 5,903
  • 3
  • 24
  • 20
  • Is that a class method of UIApplication or an instance method? And what about the second one? I guess I need to write some code to interrogate UIApplication's private methods... – Duncan C Sep 15 '15 at 15:30
  • This method signature is crashing at runtime: `- (UIInterfaceOrientation) _getSpringBoardOrientation` – Duncan C Sep 15 '15 at 15:31
  • It's an instance method on UIApplication. `[[UIApplication sharedApplication] activeInterfaceOrientation]` should work, at least it does in lldb. – Sascha Sep 15 '15 at 15:40
  • Oh, my bad. I made a mistake and made it a method of UIDevice, not UIApplication. Interesting that a method of the application object tells you the orientation of another app. – Duncan C Sep 15 '15 at 16:14
  • The `[[UIApplication sharedApplication] activeInterfaceOrientation]` method appears to give me exactly what I need. Thanks! (voted and accepted.) – Duncan C Sep 15 '15 at 16:15
0

I asked Apple this question, he replied that to use the Core Motion.

nathanwhy
  • 5,884
  • 1
  • 12
  • 13