Skip to content

Commit 14c8e23

Browse files
author
Darin Krauss
authored
Fix alert presentation bug introduced with app restructuring (#376)
- Present alert using topmost view controller of root view controller - Use window provider protocol to defer window resolution
1 parent cb704c1 commit 14c8e23

File tree

3 files changed

+22
-19
lines changed

3 files changed

+22
-19
lines changed

Loop/AppDelegate.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import UIKit
1010
import LoopKit
1111

1212
@UIApplicationMain
13-
final class AppDelegate: UIResponder, UIApplicationDelegate {
13+
final class AppDelegate: UIResponder, UIApplicationDelegate, WindowProvider {
1414
var window: UIWindow?
1515

1616
private let loopAppManager = LoopAppManager()
@@ -21,8 +21,8 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
2121
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
2222
log.default("%{public}@ with launchOptions: %{public}@", #function, String(describing: launchOptions))
2323

24-
loopAppManager.initialize(with: launchOptions)
25-
loopAppManager.launch(into: window)
24+
loopAppManager.initialize(windowProvider: self, launchOptions: launchOptions)
25+
loopAppManager.launch()
2626
return loopAppManager.isLaunchComplete
2727
}
2828

@@ -54,7 +54,7 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
5454

5555
func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) {
5656
if !loopAppManager.isLaunchComplete {
57-
loopAppManager.launch(into: window)
57+
loopAppManager.launch()
5858
}
5959
}
6060

Loop/Managers/LoopAppManager.swift

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ public extension AlertPresenter {
3232
func dismiss(animated: Bool) { dismiss(animated: animated, completion: nil) }
3333
}
3434

35+
protocol WindowProvider: AnyObject {
36+
var window: UIWindow? { get }
37+
}
38+
3539
class LoopAppManager: NSObject {
3640
private enum State: Int {
3741
case initialize
@@ -43,8 +47,8 @@ class LoopAppManager: NSObject {
4347
var next: State { State(rawValue: rawValue + 1) ?? .launchComplete }
4448
}
4549

50+
private weak var windowProvider: WindowProvider?
4651
private var launchOptions: [UIApplication.LaunchOptionsKey: Any]?
47-
private var window: UIWindow?
4852

4953
private var pluginManager: PluginManager!
5054
private var bluetoothStateManager: BluetoothStateManager!
@@ -60,18 +64,19 @@ class LoopAppManager: NSObject {
6064

6165
// MARK: - Initialization
6266

63-
func initialize(with launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
67+
func initialize(windowProvider: WindowProvider, launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
6468
dispatchPrecondition(condition: .onQueue(.main))
6569
precondition(state == .initialize)
6670

71+
self.windowProvider = windowProvider
6772
self.launchOptions = launchOptions
6873

6974
registerBackgroundTasks()
7075

7176
self.state = state.next
7277
}
7378

74-
func launch(into window: UIWindow?) {
79+
func launch() {
7580
dispatchPrecondition(condition: .onQueue(.main))
7681
precondition(!isLaunchComplete)
7782
precondition(state != .initialize)
@@ -81,9 +86,7 @@ class LoopAppManager: NSObject {
8186
return
8287
}
8388

84-
self.window = window
85-
86-
window?.tintColor = .loopAccent
89+
windowProvider?.window?.tintColor = .loopAccent
8790
OrientationLock.deviceOrientationController = self
8891
UNUserNotificationCenter.current().delegate = self
8992

@@ -128,7 +131,7 @@ class LoopAppManager: NSObject {
128131
deviceDataManager: deviceDataManager,
129132
servicesManager: deviceDataManager.servicesManager,
130133
loopDataManager: deviceDataManager.loopManager,
131-
window: window,
134+
windowProvider: windowProvider,
132135
userDefaults: UserDefaults.appGroup!)
133136

134137
deviceDataManager.analyticsServicesManager.application(didFinishLaunchingWithOptions: launchOptions)
@@ -259,20 +262,20 @@ class LoopAppManager: NSObject {
259262
}
260263

261264
private var rootViewController: UIViewController? {
262-
get { window?.rootViewController }
263-
set { window?.rootViewController = newValue }
265+
get { windowProvider?.window?.rootViewController }
266+
set { windowProvider?.window?.rootViewController = newValue }
264267
}
265268
}
266269

267270
// MARK: - AlertPresenter
268271

269272
extension LoopAppManager: AlertPresenter {
270273
func present(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)?) {
271-
rootViewController?.present(viewControllerToPresent, animated: animated, completion: completion)
274+
rootViewController?.topmostViewController.present(viewControllerToPresent, animated: animated, completion: completion)
272275
}
273276

274277
func dismiss(animated: Bool, completion: (() -> Void)?) {
275-
rootViewController?.dismiss(animated: animated, completion: completion)
278+
rootViewController?.topmostViewController.dismiss(animated: animated, completion: completion)
276279
}
277280
}
278281

Loop/Managers/OnboardingManager.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class OnboardingManager {
1616
private let deviceDataManager: DeviceDataManager
1717
private let servicesManager: ServicesManager
1818
private let loopDataManager: LoopDataManager
19-
private let window: UIWindow?
19+
private weak var windowProvider: WindowProvider?
2020
private let userDefaults: UserDefaults
2121

2222
private var isOnboarded: Bool {
@@ -31,13 +31,13 @@ class OnboardingManager {
3131

3232
private var completion: (() -> Void)?
3333

34-
init(pluginManager: PluginManager, bluetoothProvider: BluetoothProvider, deviceDataManager: DeviceDataManager, servicesManager: ServicesManager, loopDataManager: LoopDataManager, window: UIWindow?, userDefaults: UserDefaults = .standard) {
34+
init(pluginManager: PluginManager, bluetoothProvider: BluetoothProvider, deviceDataManager: DeviceDataManager, servicesManager: ServicesManager, loopDataManager: LoopDataManager, windowProvider: WindowProvider?, userDefaults: UserDefaults = .standard) {
3535
self.pluginManager = pluginManager
3636
self.bluetoothProvider = bluetoothProvider
3737
self.deviceDataManager = deviceDataManager
3838
self.servicesManager = servicesManager
3939
self.loopDataManager = loopDataManager
40-
self.window = window
40+
self.windowProvider = windowProvider
4141
self.userDefaults = userDefaults
4242

4343
self.isOnboarded = userDefaults.onboardingManagerIsOnboarded
@@ -112,7 +112,7 @@ class OnboardingManager {
112112
onboardingViewController.serviceOnboardDelegate = servicesManager
113113
onboardingViewController.completionDelegate = self
114114

115-
window?.rootViewController = onboardingViewController
115+
windowProvider?.window?.rootViewController = onboardingViewController
116116
}
117117

118118
private func completeActiveOnboarding() {

0 commit comments

Comments
 (0)