Matt Coneybeare

MC

How to Detect When an App Is Coming From the Lockscreen or Homescreen on iOS 7

| Comments

My Hourly News App has different behavior when becoming active from the Lockscreen (locked while active), or becoming active from anything else. The App includes a “Play on Launch” feature which auto-starts the audio news when the App is opened, allowing it to be a one-tap App.

Detecting whether or not the App became active from the Lockscreen vs the Homescreen is crucial so that it doesn’t auto-play when the user comes from the Lockscreen. This scenario comes about when the user starts the App, then the screen-lock kicks in, then the user comes back when the news stops. We don’t want to auto-play the news again in this scenario, just when the user taps the App icon from the Homescreen.

On iOS 6 and lower I could detect this using the current UIApplicationState in applicationWillEnterForeground

1
2
3
4
5
UIApplicationState state = [[UIApplication sharedApplication] ApplicationState];
if (UIApplicationStateInactive == state)
    // Coming from locked screen (iOS 6)
else
    // Coming from Springboard, another App, etc...

But on iOS 7, the state value is UIApplicationStateBackground in both scenarios. It seems that this is the intended behavior now, so how can I properly detect whether the App is launching from the Lockscreen?

I was able to figure out a hack on this and so far seems to be reliable. It only works on the device, not the simulator, and has been tested on an iPhone 5s, 5 and 4S running iOS 7.

It seems that there is no possible way to detect where the App is being launched from on iOS 7, but there is a way to detect if you are going to the Lockscreen vs Homescreen (or something else). The trick is to read the screen brightness in applicationDidEnterBackground. When the App hits the background due to the lock button being pressed or an auto-lock timeout, the brightness will be 0.0 on iOS 7. Otherwise, it will be > 0 when the home button is pressed or another App launched from the multitask selector or notification center.

1
2
3
4
5
- (void)applicationDidEnterBackground:(UIApplication *)application {
    CGFloat screenBrightness = [[UIScreen mainScreen] brightness];
    NSLog(@"Screen brightness: %f", screenBrightness);
    self.backgroundedToLockScreen = screenBrightness <= 0.0;
}

Now that we have an ivar holding this info, we can use it in applicationWillEnterForeground to determine the App flow.

1
2
3
4
5
6
7
8
- (void)applicationWillEnterForeground:(UIApplication *)application {
    if (self.backgroundedToLockScreen) {
        ... // App was backgrounded to lock screen
    } else {
        ... // App was backgrounded on purpose by tapping the home button or switching Apps.
    }
    self.backgroundedToLockScreen = NO;
}

It is not the exact same as the iOS 6 behavior though. As shown above, on iOS 6 you could inspect the UIApplicationState to detect where you were coming from, and this hack answers the similar, but not exactly the same, question of where you were going when the App was backgrounded. For example, perhaps the App was backgrounded due to a screen-lock timeout, but then a notification for another App woke the device, and the user went there directly from the Lockscreen then back to my App. My App would have determined on backgrounding that the user went to the Lockscreen, but when they come back they are actually coming from an active screen. For Hourly News, this difference is negligible, but your milage may vary.

So what about older OS support? Hourly News also supports iOS 6 so I needed to get the old behavior too. Simple. Just add the Application state monitoring to the foreground method.

1
2
3
4
5
6
7
8
9
10
11
- (void)applicationWillEnterForeground:(UIApplication *)application {
    UIApplicationState state = [[UIApplication sharedApplication] ApplicationState];
    if (UIApplicationStateInactive == state ||  // detect if coming from locked screen (iOS 6)
        self.backgroundedToLockScreen)          // detect if backgrounded to the Lockscreen (iOS 7)
    {
        ... // App is coming from or was backgrounded to lock screen
    } else {
        ... // App was backgrounded on purpose by tapping the home button or switching Apps
    }
    self.backgroundedToLockScreen = NO;
}

I am not sure exactly how reliable the brightness reading is, or whether or not it will change in future OS builds, but in the meantime, this hack seems to be the best we can get. Hope this helps.

Lastly, I run a small software company called Urban Apps. It pays the bills so I can take the time to write helpful posts like this one. If you found this posting helpful at all, I would really appreciate it if you would check out my iPhone/iPad Apps on the iTunes App Store.

Comments

My name is Matt Coneybeare, I design and develop for iOS (iPhone, iPad and iPod Touch), Mac OS X and the Web out of New York. In 2008 I started a software company called Urban Apps that has made some pretty popular apps such as Ambiance and Hourly News. My current Stack Overflow reputation is about 27k.

I was a Rockstar a decade ago, but then went back to school and collected a Bachelor's Degree in Computer Science from U.C. Berkeley. Now I am settled down with my beautiful wife Di and our two doggies Hamachi and Foxy. While coding, I walk several miles/day on my Treadmill Desk. When not at my desk, I love exploring New York City as a Yelp Elite, or training for marathons.

Contact information

Name
Matt Coneybeare
Email
Website
Twitter
Instagram
GitHub
LinkedIn
Google+