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

Consider App Extension environment #23

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Consider App Extension environment #23

wants to merge 4 commits into from

Conversation

devxoul
Copy link
Member

@devxoul devxoul commented May 2, 2017

Another workaround for #22, which does not make subspec.

UIApplication.shared is unavailable on AppExtension environment. Use Selector to get the first window of UIApplication's shared instance. There will be no window if the application is running on AppExtension.

@ianyh
Copy link

ianyh commented May 2, 2017

Hm. My main concern here would be not passing review. I just tested it and in an app extension it does respond to sharedApplication, returns an application object, and then returns the first window, but the windows appear to not be the extension's windows.

From RxKeyboard.applicationWindow:

(lldb) po application!
<UIApplication: 0x7f94a1201540>


(lldb) po application!.windows
▿ 3 elements
  - 0 : <UITextEffectsWindowHosted: 0x7f94a1212f40; frame = (0 0; 375 667); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x61000002e140>>
  - 1 : <UITextEffectsWindowHosted: 0x7f949e407430; frame = (0 0; 375 667); hidden = YES; layer = <UIWindowLayer: 0x600000031600>>
  - 2 : <UIRemoteKeyboardWindowHosted: 0x7f949e50b410; frame = (0 0; 375 667); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x60800002c020>>

From the extension's view controller:

(lldb) po self.view!.window!
<_UIHostedWindow: 0x7f949e506a20; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x608000250290>; layer = <UIWindowLayer: 0x60800002fb00>>

It's unclear to me what that UIApplication object actually is.

Possibly we can add an initializer to RxKeyboard that accepts a window, and make the current initializer a convenience initializer

  init(window: UIWindow?) {
    ...
  }

  override convenience init() {
    init(window: RxKeyboard.applicationWindow())
  }

Then extensions can initialize their own RxKeyboard instance instead of using the shared instance. instance would need to be lazily loaded to prevent the implicit access of the shared application, but I think static variables are already lazily loaded in swift.

@ianyh
Copy link

ianyh commented May 2, 2017

Did a bit more testing and it seems like the interactive frame changes don't work from a share extension, so there's definitely something weird with those windows.

@devxoul
Copy link
Member Author

devxoul commented May 3, 2017

@ianyh, oh I just tested with Today extension and there was no window. 🤔 I think the best option is not to include RxKeyboard to extension target but I'll dig into this more.

@ianyh
Copy link

ianyh commented May 3, 2017

I expect today extensions are hosted differently than share extensions are. Share extensions are hosted by an application's process, so there would be different dynamics. Just not including the library doesn't really make sense. It's the correct behavior for what I want to be doing, so if I don't include the library I'm just going to end up writing something myself that's going to turn out the same. Seems silly.

@devxoul
Copy link
Member Author

devxoul commented May 4, 2017

@ianyh, I've added some new commits! Now RxKeyboard has gestureView as a public property. Set this value with the App Extension's root view controller's view to use interactive keyboard dismiss mode.

// ShareViewController.swift
RxKeyboard.instance.gestureView = self.view // add this line
RxKeyboard.instance.visibleHeight.drive(...)

I also added a ShareExtension example. Check this out for working example :)

@ianyh
Copy link

ianyh commented May 4, 2017

This still triggers the UIApplication getter. It's let so it's not lazy loaded. Even if you make it lazy loaded, though, the startWith combined with the nil coalescing means that the getter gets triggered anyway when the instance is initialized, which happens before you can set the gesture's view on it. So this is the correct feature behavior, but still might not pass muster because of accessing the UIApplication.

@devxoul
Copy link
Member Author

devxoul commented May 5, 2017

@ianyh, which are you worrying about? (1) using "sharedApplication" selector or (2) accessing UIApplication instance. For (1), we can use responder chain instead to get current application instance.

@ianyh
Copy link

ianyh commented May 5, 2017

I'm worried about both, but accessing it is probably worse.

@devxoul
Copy link
Member Author

devxoul commented May 9, 2017

@ianyh, Hmm, I think this is not a private API so apple won't reject it but I'm not sure 🤔

@devxoul
Copy link
Member Author

devxoul commented May 9, 2017

@ianyh, MBProgressHUD uses this method too and there's no any open issue about the apple review.

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.

None yet

2 participants