how to detect the locked/unlocked screen status with swift

I need to detect if the screen il locked or unlocked when my app is running in background.

I can't find documentation regarding this matter for swift programming.

Some source reference ?

Replies

I wish simply to send the notifications only when the screen is unlocked and avoid them when is locked.

It depends on what you mean by screen locked. If you mean requires a passcode or Touch ID to use, you can get that state via the

isProtectedDataAvailable
property of UIApplication (and there are associated notifications for when it changes). For the other common uses of the term (screen dark, screen awake but showing system UI), there are no supported APIs to detect those states.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
  • Hi,

    Can we use isProtectedDataAvailable property for lock state detection(requires a passcode or Touch ID) only without adding Data Protection Entitlement because In [https://developer.apple.com/documentation/uikit/uiapplication/1622925-isprotecteddataavailable) says that "if data protection is enabled". So without data protection entitlement added can we check lock screen state with isProtectedDataAvailable property itself?

Add a Comment

Hi Quinn,


Is there any way of doing the same from an extension, like a today widget? I would like to detect if the device is locked or not, and change the info displayed depending on if protected data is available or not.


Thanks,


Vicente

Have you tried using the notifications provided for this (

UIApplicationProtectedDataWillBecomeUnavailable
and
UIApplicationProtectedDataDidBecomeAvailable
)?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
  • Hi, I have tried this but have found this to be inconsistent. The UIApplicationProtectedDataWillBecomeUnavailable is not called every time the device is locked. It is not called immediately after the lock event, and sometimes misses the event altogether. Is there a different approach to this problem that guarantees detecting lock & unlock correctly every time?

Add a Comment

Hi,


These notifications are available if the user use a passcode or touchID.


Is that a way to use this without a passcode and check if the user lock and unlock his Phone ?

Maybe in simulating the protection or write a secure file in the app ?


Thank you very Much.


Best Regards Gabriel.

Is that a way to use this without a passcode and check if the user lock and unlock his Phone ?

No, because these are not about screen lock they are about data protection. My post from 28 Dec was pretty clear about the difference.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

>> Have you tried using the notifications provided for this (

UIApplicationProtectedDataWillBecomeUnavailable
and
UIApplicationProtectedDataDidBecomeAvailable
)?


Ok, I can get notified about the state change, but how can I find the initial state (device locked / unlocked) when my Today Widget appears? I can see that "Find Friends" widget does this for security reasons, but it's made by Apple so perhaps it uses some private APIs. Say we have a smart home solution and we want to remotely disarm the alarm or even open the door - it would be a serious problem if such functionality is available on the locked screen without passcode check, while on the other hand it's very useful if the phone is unlocked.

I can see that "Find Friends" widget does this for security reasons, but it's made by Apple …

Right. Built-in system components, like Find Friends, are not subject to the iOS SDK’s constraints.

how can I find the initial state (device locked / unlocked) when my Today Widget appears?

That’s tricky because the

protectedDataAvailable
property is on
UIApplication
, and app extensions don’t have access to that. The best solution I can think of is to create a dummy file (or keychain item) with the right protection class and try to access it. That access will only work if protected data is available.

Given the above it seems like an enhancement request is in order here; please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I've just opened a bug 37307307 for this. Thank you for your answer.

Hi there,

Is there an update to mentioned 37307307? I'm looking for a way to get a notification within my network extension whenever there is a change to
Code Block
protectedDataAvailable


Thanks!

Is there an update to mentioned 37307307?

No.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hello ! I know this question is getting old, but we're bumping into this issue as well.

After migrating to XCode 13, it became mandatory to set APPLICATION_EXTENSION_API_ONLY to true in build settings of our widget extension. However, as stated above, this renders the isProtectedDataAvailable property unavailable through UIApplication.shared

So I have 2 questions :

  • Is there any new way of accessing it cleanly with iOS 14 or 15 ?
  • In the meantime, is it acceptable to use this ugly hack or can this be seen as accessing private API & subject to app rejection 🥶 ?
func isProtectedDataAvailable() -> Bool {
  let application = UIApplication.value(forKeyPath: #keyPath(UIApplication.shared)) as! UIApplication
  return application.isProtectedDataAvailable
}

Thanks in advance

Bioche

OK, let’s start with this:

is it acceptable to use this ugly hack

UIApplication is deliberately not available in an app extension and using KVC to get around that limitation is not acceptable.

in build settings of our widget extension

Can you explain more about why your widget extension needs this?

I’m not an expert on this stuff, but my understanding is that modern widgets do this via the redaction mechanism, as discussed in WWDC 2021 Session 10048 Principles of great widgets.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for your answer !

Can you explain more about why your widget extension needs this?

It's not a WidgetKit extension but an old Today widget that's presenting a remote control of an IoT vacuum cleaner (start / stop etc...).

These commands can only be sent if the phone is unlocked because we need to access protected tokens in keychain. That's where isProtectedDataAvailable comes in.

By "modern widget", I assume you're talking about WidgetKit. Unfortunately, we can't switch to this for now because of its limitations, mainly the fact that you can't interact with it without opening the app :/

Thanks again

Bioche

It's not a WidgetKit extension but an old Today widget

OK.

These commands can only be sent if the phone is unlocked because we need to access protected tokens in keychain.

OK. But where does the notification requirement come into this?

If you try to send a command and the device is locked, data protection will prevent you from accessing the keychain items and you’ll get a reasonable error. What do you need the notification for?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"