Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use window instead of pushing the lock onto the view controller #65

Open
wants to merge 9 commits into
base: daz/support_carthage_watchos
Choose a base branch
from

Conversation

ayanonagon
Copy link
Contributor

No description provided.

hierarchy

This is cleaner and also lets us show the lock when app switching too
so the user can hide sensitive information behind the lock when in the
app switch viewer.
@eliperkins eliperkins self-assigned this Sep 30, 2015
@eliperkins
Copy link
Contributor

Hm... Looks like Travis isn't too happy about Xcode 6.3... Any idea why we ended up with a box with 6.3 instead of 6.4?

@eliperkins
Copy link
Contributor

Code looks good though!

@zinthemoney you wanna take a look at this change too, for a second set of 👀? I know you mentioned at DubDub this year that you're using this in Chime, so I just wanted to make sure these changes don't break too much for y'all!

@zinthemoney
Copy link
Contributor

@ayanonagon, can you give a little background / problems on start using the window?

@eliperkins, by replacing VENTouchLock 1.11.0 with branch an/fix on my project, it doesn't work as before. I will take a deeper look later.

@ayanonagon
Copy link
Contributor Author

@zinthemoney Sure! Two main reasons:

  1. It’s not cool that the current VENTouchLock mucks around with your app’s view controller hierarchy. By having a separate window, it’s a lot cleaner to maintain, and doesn’t need to care about stuff going on in the app’s main window.
  2. We can more reliably take a snapshot of the app when it goes into background mode, so we can cover sensitive data when the app is show in the app switcher.

Let me know if you have any more questions. Thanks for trying it out :D

UIWindow *mainWindow = [[UIApplication sharedApplication].windows firstObject];
UIViewController *rootViewController = [UIViewController ventouchlock_topMostController];
UIViewController *displayController;
self.lockWindow = [[UIWindow alloc] initWithFrame:self.mainWindow.frame];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about adding:

self.lockWindow.windowLevel = UIWindowLevelAlert; // or UIWindowLevelAlert + 1

?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will give us the benefit of overlaying other windows which reside at lower, more normal levels.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! Done.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up the UIWindowLevel doesn't help in the situation i mentioned, by the same token that UIApplication is a shared instance. Basically, we want to make sure that we call [self.lockWindow makeKeyAndVisible]; last with respect to whatever the host app might be doing. Hope this makes sense :)

By introducing a delay helps, but not ideal

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [self.lockWindow makeKeyAndVisible];

});

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation for -makeKeyAndVisible says that the method makes sure the window is displayed above all other windows with the same window level or lower.

This is a convenience method to make the receiver the main window and displays it in front of other windows at the same window level or lower.

To address your concerns, @zinthemoney, I propose doing a few things to guard against becoming obscured and to alert developers to the possibility that their app may be doing something that collides with how VENTouchLock operates.

  1. On the invocation of -lock, check if -[UIApplication windows] has more than 1 window and -[UIApplication keyWindow] is not equal to -[id<UIApplicationDelegate> window]. If this is the case, we should set lockWindow's windowLevel to be equal to the windowLevel of the currently key window.
  2. Make our lock window a UIWindow subclass that overrides -setRootViewController: and raises an assertion if the argument is any type of view controller that we don't expect. This won't crash in release builds but will crash in debug builds.
  3. Observe the UIWindowDidBecomeKeyNotification and UIWindowDidBecomeVisibleNotification notifications. If we're currently locked and we receive these messages, raise an assertion that informs the developer that they've attempted to display a window on top of VENTouchLock and that this is undefined behavior.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hyperspacemark I agree with your points, my only concern on having this obscured behavior that (potentially) breaks existing VENTouchLock integrations is adding integration complexity. We should solve the issue within the framework, and not pass on the responsibility to the developers. @ayanonagon, @eliperkins what do you think?

@eliperkins
Copy link
Contributor

@zinthemoney ah, certainly true. The idea spurned out of some information from this blog post: http://www.thecave.com/2015/09/28/how-to-present-an-alert-view-using-uialertcontroller-when-you-dont-have-a-view-controller/, specifically:

At WWDC I stopped in at one of the labs and asked an Apple Engineer this same question: “What was the best practice for displaying a UIAlertController?” And he said they had been getting this question a lot and we joked that they should have had a session on it. He said that internally Apple is creating a UIWindow with a transparent UIViewController and then presenting the UIAlertController on it.

I think setting the window level might help us mitigate some of those concerns: https://github.com/venmo/VENTouchLock/pull/65/files#r40910236 by at least placing our window over the rest. I'll have to check to see if this accomplishes what you're discussing, however, that touching our application's window will definitely have some interesting side-effects.

might not necessarily hide the window if the other window’s level is
lower
[notificationCenter addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
[notificationCenter addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];

self.mainWindow = [[UIApplication sharedApplication].windows firstObject];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we be sure this is the application's main window? It might be better to directly ask UIApplication's delegate for its window?

@dasmer
Copy link
Contributor

dasmer commented Apr 5, 2016

@ayanonagon what's the status of this PR?

@eliperkins eliperkins removed their assignment Apr 5, 2017
@ghost
Copy link

ghost commented Oct 10, 2017

What's the status on this PR?

@ericlewis
Copy link
Contributor

Not to speak for everyone, but as an active maintainer we haven’t been focused on implementing this. If you’d like to chat with me or test or suggest things we’d love to hear it. But as it stands this implementation doesn’t function for everyone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants