Skip to content
This repository was archived by the owner on Feb 5, 2025. It is now read-only.

Commit 61af6e8

Browse files
authored
Merge pull request #775 from wordpress-mobile/fix/21075-fix-retain-cycles-between-button-actions-and-view-controllers
Break retain cycles between button onTap action and view controllers
2 parents bfdfde6 + 7abaa99 commit 61af6e8

15 files changed

+158
-31
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ _None._
4848

4949
_None._
5050

51+
## 6.3.0
52+
53+
### Bug Fixes
54+
55+
- Fix retain cycles by using `weak self` in action closures. [#775]
56+
5157
## 6.2.0
5258

5359
### Bug Fixes

Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ PODS:
2222
- SVProgressHUD (2.2.5)
2323
- SwiftLint (0.49.1)
2424
- UIDeviceIdentifier (2.2.0)
25-
- WordPressAuthenticator (6.2.0):
25+
- WordPressAuthenticator (6.3.0-beta.1):
2626
- GoogleSignIn (~> 6.0.1)
2727
- Gridicons (~> 1.0)
2828
- "NSURL+IDN (= 0.4)"
@@ -94,7 +94,7 @@ SPEC CHECKSUMS:
9494
SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6
9595
SwiftLint: 32ee33ded0636d0905ef6911b2b67bbaeeedafa5
9696
UIDeviceIdentifier: f33af270ba9045ea18b31d9aab88e42a0082ea67
97-
WordPressAuthenticator: 8a27a3c61ca0d740df66f260902aa2ca8528c61b
97+
WordPressAuthenticator: 5e3514db04817d1ee24feda3e7e979984c991af8
9898
WordPressKit: 8e1c5a64645a59493a7316f38468ac036de9c79b
9999
WordPressShared: 0aa459e5257a77184db87805a998f447443c9706
100100
WordPressUI: 1cf47a3b78154faf69caa18569ee7ece1e510fa0

WordPressAuthenticator.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Pod::Spec.new do |s|
44
s.name = 'WordPressAuthenticator'
5-
s.version = '6.2.0'
5+
s.version = '6.3.0-beta.1'
66

77
s.summary = 'WordPressAuthenticator implements an easy and elegant way to authenticate your WordPress Apps.'
88
s.description = <<-DESC

WordPressAuthenticator.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
0193F7752A615521004D7C16 /* MemoryManagementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0193F7742A615521004D7C16 /* MemoryManagementTests.swift */; };
1011
020BE74A23B0BD2E007FE54C /* WordPressAuthenticatorDisplayImages.swift in Sources */ = {isa = PBXBuildFile; fileRef = 020BE74923B0BD2E007FE54C /* WordPressAuthenticatorDisplayImages.swift */; };
1112
020DEF6428AA091100C85D51 /* MagicLinkRequester.swift in Sources */ = {isa = PBXBuildFile; fileRef = 020DEF6328AA091100C85D51 /* MagicLinkRequester.swift */; };
1213
02A526CA28A3499C00FD1812 /* MagicLinkRequestedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02A526C828A3499C00FD1812 /* MagicLinkRequestedViewController.swift */; };
@@ -261,6 +262,7 @@
261262
/* End PBXCopyFilesBuildPhase section */
262263

263264
/* Begin PBXFileReference section */
265+
0193F7742A615521004D7C16 /* MemoryManagementTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryManagementTests.swift; sourceTree = "<group>"; };
264266
020BE74923B0BD2E007FE54C /* WordPressAuthenticatorDisplayImages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordPressAuthenticatorDisplayImages.swift; sourceTree = "<group>"; };
265267
020DEF6328AA091100C85D51 /* MagicLinkRequester.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MagicLinkRequester.swift; sourceTree = "<group>"; };
266268
02A526C828A3499C00FD1812 /* MagicLinkRequestedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MagicLinkRequestedViewController.swift; sourceTree = "<group>"; };
@@ -956,6 +958,7 @@
956958
3F86A83F29D280DC005D20C0 /* SingIn */,
957959
F18DF0E32525009200D83AFE /* SupportingFiles */,
958960
3F338B6B289B87E60014ADC5 /* UnitTests.xctestplan */,
961+
0193F7742A615521004D7C16 /* MemoryManagementTests.swift */,
959962
);
960963
path = WordPressAuthenticatorTests;
961964
sourceTree = "<group>";
@@ -1552,6 +1555,7 @@
15521555
buildActionMask = 2147483647;
15531556
files = (
15541557
3F4E64782990BBD4000DB555 /* IDTokenTests.swift in Sources */,
1558+
0193F7752A615521004D7C16 /* MemoryManagementTests.swift in Sources */,
15551559
3F86A84E29D3B53D005D20C0 /* SocialServiceTests.swift in Sources */,
15561560
3F879FDB293A49AA005C2B48 /* NewGoogleAuthenticatorTests.swift in Sources */,
15571561
F18DF0E5252500A600D83AFE /* WordPressAuthenticatorTests-Bridging-Header.h in Sources */,

WordPressAuthenticator/NUX/NUXTableViewController.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ open class NUXTableViewController: UITableViewController, NUXViewControllerBase,
1818
return UIDevice.isPad() ? .all : .portrait
1919
}
2020

21+
// MARK: - Private
22+
private var notificationObservers: [NSObjectProtocol] = []
23+
2124
override open func viewDidLoad() {
2225
super.viewDidLoad()
2326
setupHelpButtonIfNeeded()
@@ -27,4 +30,17 @@ open class NUXTableViewController: UITableViewController, NUXViewControllerBase,
2730
public func shouldShowCancelButton() -> Bool {
2831
return shouldShowCancelButtonBase()
2932
}
33+
34+
// MARK: - Notification Observers
35+
36+
public func addNotificationObserver(_ observer: NSObjectProtocol) {
37+
notificationObservers.append(observer)
38+
}
39+
40+
deinit {
41+
for observer in notificationObservers {
42+
NotificationCenter.default.removeObserver(observer)
43+
}
44+
notificationObservers.removeAll()
45+
}
3046
}

WordPressAuthenticator/NUX/NUXViewController.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ open class NUXViewController: UIViewController, NUXViewControllerBase, UIViewCon
1717
}
1818
}
1919

20+
// MARK: - Private
21+
private var notificationObservers: [NSObjectProtocol] = []
22+
2023
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
2124
return UIDevice.isPad() ? .all : .portrait
2225
}
@@ -53,6 +56,19 @@ open class NUXViewController: UIViewController, NUXViewControllerBase, UIViewCon
5356
public func shouldShowCancelButton() -> Bool {
5457
return shouldShowCancelButtonBase()
5558
}
59+
60+
// MARK: - Notification Observers
61+
62+
public func addNotificationObserver(_ observer: NSObjectProtocol) {
63+
notificationObservers.append(observer)
64+
}
65+
66+
deinit {
67+
for observer in notificationObservers {
68+
NotificationCenter.default.removeObserver(observer)
69+
}
70+
notificationObservers.removeAll()
71+
}
5672
}
5773

5874
extension NUXViewController {

WordPressAuthenticator/NUX/NUXViewControllerBase.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ public protocol NUXViewControllerBase {
2828
///
2929
func shouldShowCancelButton() -> Bool
3030
func setupCancelButtonIfNeeded()
31+
32+
/// Notification observers that can be tied to the lifecycle of the entities implementing the protocol
33+
func addNotificationObserver(_ observer: NSObjectProtocol)
3134
}
3235

3336
/// extension for NUXViewControllerBase where the base class is UIViewController (and thus also NUXTableViewController)
@@ -286,12 +289,17 @@ extension NUXViewControllerBase where Self: UIViewController, Self: UIViewContro
286289
private func setupNotificationsIndicator() {
287290
helpNotificationIndicator.isHidden = true
288291

289-
NotificationCenter.default.addObserver(forName: .wordpressSupportNotificationReceived, object: nil, queue: nil) { [weak self] _ in
290-
self?.refreshSupportNotificationIndicator()
291-
}
292-
NotificationCenter.default.addObserver(forName: .wordpressSupportNotificationCleared, object: nil, queue: nil) { [weak self] _ in
293-
self?.refreshSupportNotificationIndicator()
294-
}
292+
addNotificationObserver(
293+
NotificationCenter.default.addObserver(forName: .wordpressSupportNotificationReceived, object: nil, queue: nil) { [weak self] _ in
294+
self?.refreshSupportNotificationIndicator()
295+
}
296+
)
297+
298+
addNotificationObserver(
299+
NotificationCenter.default.addObserver(forName: .wordpressSupportNotificationCleared, object: nil, queue: nil) { [weak self] _ in
300+
self?.refreshSupportNotificationIndicator()
301+
}
302+
)
295303
}
296304

297305
private func layoutNotificationIndicatorView(_ view: UIView, to superView: UIView) {

WordPressAuthenticator/Signin/LoginPrologueLoginMethodViewController.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ class LoginPrologueLoginMethodViewController: NUXViewController {
6060
self.emailTapped?()
6161
}
6262

63-
buttonViewController.setupButtomButtonFor(socialService: .google, onTap: handleGoogleButtonTapped)
63+
buttonViewController.setupButtomButtonFor(socialService: .google) { [weak self] in
64+
self?.handleGoogleButtonTapped()
65+
}
6466

6567
if !LoginFields().restrictToWPCom && selfHostedTapped != nil {
6668
let selfHostedLoginButton = WPStyleGuide.selfHostedLoginButton(alignment: .center)
@@ -69,7 +71,9 @@ class LoginPrologueLoginMethodViewController: NUXViewController {
6971
}
7072

7173
if WordPressAuthenticator.shared.configuration.enableSignInWithApple {
72-
buttonViewController.setupTertiaryButtonFor(socialService: .apple, onTap: handleAppleButtonTapped)
74+
buttonViewController.setupTertiaryButtonFor(socialService: .apple) { [weak self] in
75+
self?.handleAppleButtonTapped()
76+
}
7377
}
7478

7579
buttonViewController.backgroundColor = WordPressAuthenticator.shared.style.buttonViewBackgroundColor

WordPressAuthenticator/Signin/LoginPrologueSignupMethodViewController.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ class LoginPrologueSignupMethodViewController: NUXViewController {
5656
self?.emailTapped?()
5757
}
5858

59-
buttonViewController.setupButtomButtonFor(socialService: .google, onTap: handleGoogleButtonTapped)
59+
buttonViewController.setupButtomButtonFor(socialService: .google) { [weak self] in
60+
self?.handleGoogleButtonTapped()
61+
}
6062

6163
let termsButton = WPStyleGuide.termsButton()
6264
termsButton.on(.touchUpInside) { [weak self] _ in
@@ -76,7 +78,9 @@ class LoginPrologueSignupMethodViewController: NUXViewController {
7678
buttonViewController.stackView?.insertArrangedSubview(termsButton, at: 0)
7779

7880
if WordPressAuthenticator.shared.configuration.enableSignInWithApple {
79-
buttonViewController.setupTertiaryButtonFor(socialService: .apple, onTap: handleAppleButtonTapped)
81+
buttonViewController.setupTertiaryButtonFor(socialService: .apple) { [weak self] in
82+
self?.handleAppleButtonTapped()
83+
}
8084
}
8185

8286
buttonViewController.backgroundColor = WordPressAuthenticator.shared.style.buttonViewBackgroundColor

WordPressAuthenticator/Signin/LoginPrologueViewController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ class LoginPrologueViewController: LoginViewController {
3030
private let configuration = WordPressAuthenticator.shared.configuration
3131
private let style = WordPressAuthenticator.shared.style
3232

33-
private lazy var storedCredentialsAuthenticator = StoredCredentialsAuthenticator(onCancel: {
33+
private lazy var storedCredentialsAuthenticator = StoredCredentialsAuthenticator(onCancel: { [weak self] in
3434
// Since the authenticator has its own flow
35-
self.tracker.resetState()
35+
self?.tracker.resetState()
3636
})
3737

3838
/// We can't rely on `isMovingToParent` to know if we need to track the `.prologue` step

0 commit comments

Comments
 (0)