@@ -25,39 +25,85 @@ import UIKit
25
25
26
26
@available ( iOS 13 . 0 , * )
27
27
private static func getActiveWindowRootViewController( ) -> UIViewController ? {
28
- guard let application = AppExtensionHelper . application else { return nil }
28
+ guard let application = AppExtensionHelper . application else {
29
+ ITBDebug ( " No application found in AppExtensionHelper " )
30
+ return nil
31
+ }
32
+
33
+ ITBDebug ( " Application has \( application. connectedScenes. count) connected scenes " )
29
34
30
35
// Find active scenes (foreground active takes priority)
31
36
let activeScenes = application. connectedScenes
32
37
. compactMap { $0 as? UIWindowScene }
33
38
. filter { $0. activationState == . foregroundActive }
34
39
35
- // Look for key window in active scenes first
36
- for scene in activeScenes {
37
- if let keyWindow = scene. windows. first ( where: { $0. isKeyWindow } ) ,
38
- let rootVC = keyWindow. rootViewController {
39
- return rootVC
40
+ ITBDebug ( " Found \( activeScenes. count) foreground active scenes " )
41
+
42
+ // iOS 15+: Use scene's keyWindow property (preferred approach)
43
+ if #available( iOS 15 . 0 , * ) {
44
+ for (index, scene) in activeScenes. enumerated ( ) {
45
+ ITBDebug ( " Checking scene \( index) : keyWindow exists = \( scene. keyWindow != nil ) " )
46
+ if let keyWindow = scene. keyWindow,
47
+ let rootVC = keyWindow. rootViewController {
48
+ ITBDebug ( " Found root view controller in keyWindow: \( String ( describing: rootVC) ) " )
49
+ return rootVC
50
+ } else {
51
+ ITBDebug ( " Scene \( index) : keyWindow or rootVC is nil " )
52
+ }
53
+ }
54
+ } else {
55
+ // iOS 13-14: Fall back to isKeyWindow check
56
+ for (index, scene) in activeScenes. enumerated ( ) {
57
+ let keyWindows = scene. windows. filter { $0. isKeyWindow }
58
+ ITBDebug ( " Scene \( index) : found \( keyWindows. count) key windows " )
59
+ if let keyWindow = scene. windows. first ( where: { $0. isKeyWindow } ) ,
60
+ let rootVC = keyWindow. rootViewController {
61
+ ITBDebug ( " Found root view controller in keyWindow (iOS 13-14): \( String ( describing: rootVC) ) " )
62
+ return rootVC
63
+ } else {
64
+ ITBDebug ( " Scene \( index) : no keyWindow with rootVC found " )
65
+ }
40
66
}
41
67
}
42
68
43
69
// Fallback to first window in first active scene
44
70
if let firstActiveScene = activeScenes. first,
45
71
let rootVC = firstActiveScene. windows. first? . rootViewController {
72
+ ITBDebug ( " Fallback: Found root view controller in first window of first active scene: \( String ( describing: rootVC) ) " )
46
73
return rootVC
74
+ } else {
75
+ ITBDebug ( " Fallback: No root view controller found in first window of first active scene " )
47
76
}
48
77
49
- // Final fallback: any foreground inactive scene with key window
78
+ // Final fallback: any foreground inactive scene
50
79
let inactiveScenes = application. connectedScenes
51
80
. compactMap { $0 as? UIWindowScene }
52
81
. filter { $0. activationState == . foregroundInactive }
53
82
54
- for scene in inactiveScenes {
55
- if let keyWindow = scene. windows. first ( where: { $0. isKeyWindow } ) ,
56
- let rootVC = keyWindow. rootViewController {
57
- return rootVC
83
+ ITBDebug ( " Checking \( inactiveScenes. count) foreground inactive scenes as final fallback " )
84
+
85
+ if #available( iOS 15 . 0 , * ) {
86
+ for (index, scene) in inactiveScenes. enumerated ( ) {
87
+ ITBDebug ( " Inactive scene \( index) : keyWindow exists = \( scene. keyWindow != nil ) " )
88
+ if let keyWindow = scene. keyWindow,
89
+ let rootVC = keyWindow. rootViewController {
90
+ ITBDebug ( " Final fallback: Found root view controller in inactive scene keyWindow: \( String ( describing: rootVC) ) " )
91
+ return rootVC
92
+ }
93
+ }
94
+ } else {
95
+ for (index, scene) in inactiveScenes. enumerated ( ) {
96
+ let keyWindows = scene. windows. filter { $0. isKeyWindow }
97
+ ITBDebug ( " Inactive scene \( index) : found \( keyWindows. count) key windows " )
98
+ if let keyWindow = scene. windows. first ( where: { $0. isKeyWindow } ) ,
99
+ let rootVC = keyWindow. rootViewController {
100
+ ITBDebug ( " Final fallback: Found root view controller in inactive scene keyWindow (iOS 13-14): \( String ( describing: rootVC) ) " )
101
+ return rootVC
102
+ }
58
103
}
59
104
}
60
105
106
+ ITBDebug ( " No root view controller found in any scene " )
61
107
return nil
62
108
}
63
109
@@ -145,73 +191,4 @@ import UIKit
145
191
return true
146
192
}
147
193
}
148
-
149
- @available ( iOS 13 . 0 , * )
150
- private static func getActiveWindowRootViewController( ) -> UIViewController ? {
151
- guard let application = AppExtensionHelper . application else { return nil }
152
-
153
- // Prioritize foregroundActive scenes for Stage Manager and multi-window scenarios
154
- for scene in application. connectedScenes {
155
- guard let windowScene = scene as? UIWindowScene ,
156
- windowScene. activationState == . foregroundActive else { continue }
157
-
158
- // Filter for visible, normal-level windows with valid rootViewControllers
159
- let visibleWindows = windowScene. windows. filter {
160
- $0. isHidden == false &&
161
- $0. windowLevel == . normal &&
162
- $0. rootViewController != nil
163
- }
164
-
165
- // Try keyWindow first if available (iOS 15+) and in our visible set
166
- if #available( iOS 15 . 0 , * ) {
167
- if let keyWindow = windowScene. keyWindow,
168
- visibleWindows. contains ( keyWindow) {
169
- return keyWindow. rootViewController
170
- }
171
- }
172
-
173
- // For iOS 13-14, find keyWindow manually in visible windows
174
- for window in visibleWindows {
175
- if window. isKeyWindow {
176
- return window. rootViewController
177
- }
178
- }
179
-
180
- // Fallback to first visible, normal window
181
- if let firstVisibleWindow = visibleWindows. first {
182
- return firstVisibleWindow. rootViewController
183
- }
184
- }
185
-
186
- // Secondary fallback: any foregroundInactive scene (Stage Manager background)
187
- for scene in application. connectedScenes {
188
- guard let windowScene = scene as? UIWindowScene ,
189
- windowScene. activationState == . foregroundInactive else { continue }
190
-
191
- let visibleWindows = windowScene. windows. filter {
192
- $0. isHidden == false &&
193
- $0. windowLevel == . normal &&
194
- $0. rootViewController != nil
195
- }
196
-
197
- if #available( iOS 15 . 0 , * ) {
198
- if let keyWindow = windowScene. keyWindow,
199
- visibleWindows. contains ( keyWindow) {
200
- return keyWindow. rootViewController
201
- }
202
- }
203
-
204
- for window in visibleWindows {
205
- if window. isKeyWindow {
206
- return window. rootViewController
207
- }
208
- }
209
-
210
- if let firstVisibleWindow = visibleWindows. first {
211
- return firstVisibleWindow. rootViewController
212
- }
213
- }
214
-
215
- return nil
216
- }
217
194
}
0 commit comments