0

for the app I'm developing, I implemented a lock screen that allows the user to unlock the App by manual-pin or touch/Face-ID.

Everything is working OK during the normal use.

However, I need to show the lock screen when the app is resumed from background and even in the task switcher to avoid "peeking" at the content without having unlocked properly.

As recommended by Apple in this (old) article, I present the lock view controller in applicationDidEnterBackground:

func applicationDidEnterBackground(_ application: UIApplication) {
   let lockVC = LoginViewController()
   lockVC.loginType = LoginViewController.LoginType.resumeApp
   if let topViewController = UIApplication.topViewController() {
      topViewController.present(lockVC, animated: false, completion: nil)
   }
}

where topViewControler is a useful extension to determnine the topmost view controller: Get top most UIViewController .

The lockVC.loginType = ... is just to let the ViewController what type of login I need and customize its view a little bit

The results I get are a bit weird, both on simulator and real devices:

  • the task switcher preview for my app is completely black
  • when the app is resumed, the screen remains black as in preview and unresponsive. Only way to exit is to kill the app.
  • before obtaining the weird results above, I had to access all outlets as optional to avoid termination... that's fine for viewDidLoad stuff (I didn't expect the need for this when entering background, since the view had been loaded before - outlet wired) but the strange thing is that I had the same error for an IBAction in viewDidAppear (IBAction for touch-id button called automatically if touch/face-id is available - just a requirement).

I believe I'm missing something big here... but no other hints found.

No one of the ready-made lock screen solutions come with an example for the background/taskSwicth/resume case).

Note that the black/unresponsive screen seems to be same both if I use the mentioned extension for the topmost view controller to present or if I simply try to present it by

self.window?.rootViewController?.present(lockVC, animated: false)

(which I believe is wrong, but tried anyway)

Any help would be apreciated

Marco D.
  • 33
  • 5

2 Answers2

0

I found a temporary workaround:

  1. Display the lock screen when the app becomes active from background, as suggested by Dev_Tandel

  2. Hide information in the task switcher by adding a blur effect on the current screen where the app is sent to background (applicationWillResignActive) and removing it when the app comes active again (applicationDidBecomeActive), as suggested here

As said, it's a temporary workaround that i wanted to share, but I don't like this 100%. It is required to show the lock screen in the task swtcher and Ive seen apps doing it (e.g. "oneSafe").

Still looking for help.

Marco D.
  • 33
  • 5
0

Solved, thanks to this post. Apparently I was naive in trying to present a view controller with just its object instance.

If I use

let lockVC = topViewController.storyboard?.instantiateViewController(withIdentifier: "IDLoginViewController") as! LoginViewController

everything works, the lock screen is shown also in the task switcher, no need to blur!

Marco D.
  • 33
  • 5