@@ -33,6 +33,7 @@ public class RxKeyboard: NSObject {
33
33
34
34
// MARK: Private
35
35
36
+ fileprivate let window = RxKeyboard . applicationWindow ( )
36
37
fileprivate let disposeBag = DisposeBag ( )
37
38
fileprivate let panRecognizer = UIPanGestureRecognizer ( )
38
39
@@ -91,9 +92,9 @@ public class RxKeyboard: NSObject {
91
92
// pan gesture
92
93
let didPan = self . panRecognizer. rx. event
93
94
. withLatestFrom ( frameVariable. asObservable ( ) ) { ( $0, $1) }
94
- . flatMap { ( gestureRecognizer, frame) -> Observable < CGRect > in
95
+ . flatMap { [ weak self ] ( gestureRecognizer, frame) -> Observable < CGRect > in
95
96
guard case . changed = gestureRecognizer. state,
96
- let window = UIApplication . shared . windows . first ,
97
+ let window = self ? . window ,
97
98
frame. origin. y < UIScreen . main. bounds. height
98
99
else { return . empty( ) }
99
100
let origin = gestureRecognizer. location ( in: window)
@@ -112,12 +113,23 @@ public class RxKeyboard: NSObject {
112
113
NotificationCenter . default. rx. notification ( . UIApplicationDidFinishLaunching)
113
114
. map { _ in Void ( ) }
114
115
. startWith ( Void ( ) ) // when RxKeyboard is initialized before UIApplication.window is created
115
- . subscribe ( onNext: { _ in
116
- UIApplication . shared. windows. first? . addGestureRecognizer ( self . panRecognizer)
116
+ . subscribe ( onNext: { [ weak self] _ in
117
+ guard let `self` = self else { return }
118
+ self . window? . addGestureRecognizer ( self . panRecognizer)
117
119
} )
118
120
. addDisposableTo ( self . disposeBag)
119
121
}
120
122
123
+ /// Returns the first window of `UIApplication.shared`. Returns `nil` if the application has no
124
+ /// window. (e.g. App Extension)
125
+ private class func applicationWindow( ) -> UIWindow ? {
126
+ // use objc selector to get shared UIApplication instance from App Extension
127
+ let selector = NSSelectorFromString ( " sharedApplication " )
128
+ guard UIApplication . responds ( to: selector) else { return nil }
129
+ let application = UIApplication . perform ( selector) . takeRetainedValue ( ) as? UIApplication
130
+ return application? . windows. first
131
+ }
132
+
121
133
}
122
134
123
135
0 commit comments