Skip to content

Commit 683f915

Browse files
committed
fix(status-bar): avoid retain cycle between StatusBar and the bridge
1 parent 0bfde98 commit 683f915

1 file changed

Lines changed: 19 additions & 16 deletions

File tree

status-bar/ios/Sources/StatusBarPlugin/StatusBar.swift

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import Capacitor
33

44
public class StatusBar {
55

6-
private var bridge: CAPBridgeProtocol
6+
// Weak to avoid a retain cycle: the bridge owns this object transitively
7+
// (bridge -> plugins -> StatusBarPlugin -> statusBar), so a strong back
8+
// reference would keep the whole bridge alive forever.
9+
private weak var bridge: CAPBridgeProtocol?
710
private var isOverlayingWebview = true
811
private var backgroundColor = UIColor.black
912
private var backgroundView: UIView?
@@ -23,7 +26,7 @@ public class StatusBar {
2326
self?.handleViewDidAppear(config: config)
2427
})
2528
observers.append(NotificationCenter.default.addObserver(forName: .capacitorStatusBarTapped, object: .none, queue: .none) { [weak self] _ in
26-
self?.bridge.triggerJSEvent(eventName: "statusTap", target: "window")
29+
self?.bridge?.triggerJSEvent(eventName: "statusTap", target: "window")
2730
})
2831
observers.append(NotificationCenter.default.addObserver(forName: .capacitorViewWillTransition, object: .none, queue: .none) { [weak self] _ in
2932
self?.handleViewWillTransition()
@@ -44,7 +47,7 @@ public class StatusBar {
4447
}
4548

4649
func setStyle(_ style: UIStatusBarStyle) {
47-
bridge.statusBarStyle = style
50+
bridge?.statusBarStyle = style
4851
}
4952

5053
func setBackgroundColor(_ color: UIColor) {
@@ -54,17 +57,17 @@ public class StatusBar {
5457

5558
func setAnimation(_ animation: String) {
5659
if animation == "SLIDE" {
57-
bridge.statusBarAnimation = .slide
60+
bridge?.statusBarAnimation = .slide
5861
} else if animation == "NONE" {
59-
bridge.statusBarAnimation = .none
62+
bridge?.statusBarAnimation = .none
6063
} else {
61-
bridge.statusBarAnimation = .fade
64+
bridge?.statusBarAnimation = .fade
6265
}
6366
}
6467

6568
func hide(animation: String) {
6669
setAnimation(animation)
67-
if bridge.statusBarVisible {
70+
if let bridge, bridge.statusBarVisible {
6871
bridge.statusBarVisible = false
6972
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
7073
self?.resizeWebView()
@@ -76,7 +79,7 @@ public class StatusBar {
7679

7780
func show(animation: String) {
7881
setAnimation(animation)
79-
if !bridge.statusBarVisible {
82+
if let bridge, !bridge.statusBarVisible {
8083
bridge.statusBarVisible = true
8184
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [self] in
8285
resizeWebView()
@@ -91,7 +94,7 @@ public class StatusBar {
9194

9295
func getInfo() -> StatusBarInfo {
9396
let style: String
94-
switch bridge.statusBarStyle {
97+
switch bridge?.statusBarStyle ?? .default {
9598
case .default:
9699
style = "DEFAULT"
97100
case .lightContent:
@@ -104,7 +107,7 @@ public class StatusBar {
104107

105108
return StatusBarInfo(
106109
overlays: isOverlayingWebview,
107-
visible: bridge.statusBarVisible,
110+
visible: bridge?.statusBarVisible ?? false,
108111
style: style,
109112
color: UIColor.capacitor.hex(fromColor: backgroundColor),
110113
height: getStatusBarFrame().size.height
@@ -118,19 +121,19 @@ public class StatusBar {
118121
backgroundView?.removeFromSuperview()
119122
} else {
120123
initializeBackgroundViewIfNeeded()
121-
bridge.webView?.superview?.addSubview(backgroundView!)
124+
bridge?.webView?.superview?.addSubview(backgroundView!)
122125
}
123126
resizeWebView()
124127
}
125128

126129
private func resizeWebView() {
127-
let bounds: CGRect? = bridge.viewController?.view.window?.windowScene?.keyWindow?.bounds
130+
let bounds: CGRect? = bridge?.viewController?.view.window?.windowScene?.keyWindow?.bounds
128131

129132
guard
130-
let webView = bridge.webView,
133+
let webView = bridge?.webView,
131134
let bounds = bounds
132135
else { return }
133-
bridge.viewController?.view.frame = bounds
136+
bridge?.viewController?.view.frame = bounds
134137
webView.frame = bounds
135138
let statusBarHeight = getStatusBarFrame().size.height
136139
var webViewFrame = webView.frame
@@ -154,15 +157,15 @@ public class StatusBar {
154157
}
155158

156159
private func getStatusBarFrame() -> CGRect {
157-
return bridge.viewController?.view.window?.windowScene?.statusBarManager?.statusBarFrame ?? .zero
160+
return bridge?.viewController?.view.window?.windowScene?.statusBarManager?.statusBarFrame ?? .zero
158161
}
159162

160163
private func initializeBackgroundViewIfNeeded() {
161164
if backgroundView == nil {
162165
backgroundView = UIView(frame: getStatusBarFrame())
163166
backgroundView!.backgroundColor = backgroundColor
164167
backgroundView!.autoresizingMask = [.flexibleWidth, .flexibleBottomMargin]
165-
backgroundView!.isHidden = !bridge.statusBarVisible
168+
backgroundView!.isHidden = !(bridge?.statusBarVisible ?? false)
166169
}
167170
}
168171
}

0 commit comments

Comments
 (0)