From 9b0ade9e11856c7dc949692b61baaf769c886124 Mon Sep 17 00:00:00 2001 From: Harris Borawski Date: Mon, 6 Nov 2023 11:46:32 -0800 Subject: [PATCH] iOS: remove strong self references in plugins (#209) * iOS: remove strong self references in plugins * update pod push flag for more output --- .../Sources/BaseBeaconPlugin.swift | 4 ++-- .../Sources/SwiftUIBeaconPlugin.swift | 3 ++- .../Sources/ExpressionPlugin.swift | 7 ++++--- .../Sources/ExternalActionPlugin.swift | 6 +++--- .../ExternalActionViewModifierPlugin.swift | 16 ++++++++-------- .../MetricsPlugin/Sources/MetricsPlugin.swift | 7 ++++--- .../Sources/SwiftUICheckPathPlugin.swift | 2 +- scripts/after-shipit-pod-push.js | 2 +- 8 files changed, 25 insertions(+), 22 deletions(-) diff --git a/ios/plugins/BaseBeaconPlugin/Sources/BaseBeaconPlugin.swift b/ios/plugins/BaseBeaconPlugin/Sources/BaseBeaconPlugin.swift index aa5c60281..3fd35fec1 100644 --- a/ios/plugins/BaseBeaconPlugin/Sources/BaseBeaconPlugin.swift +++ b/ios/plugins/BaseBeaconPlugin/Sources/BaseBeaconPlugin.swift @@ -84,7 +84,7 @@ open class BaseBeaconPlugin: JSBasePlugin { for plugin in plugins { plugin.context = self.context } - let callback: @convention(block) (JSValue?) -> Void = { rawBeacon in + let callback: @convention(block) (JSValue?) -> Void = { [weak self] rawBeacon in guard let object = rawBeacon?.toObject(), let data = try? JSONSerialization.data(withJSONObject: object), @@ -92,7 +92,7 @@ open class BaseBeaconPlugin: JSBasePlugin { .inject(to: JSONDecoder()) .decode(BeaconStruct.self, from: data) else { return } - self.callback?(beacon) + self?.callback?(beacon) } let jsCallback = JSValue(object: callback, in: context) as Any return [["callback": jsCallback, "plugins": plugins.map { $0.pluginRef }]] diff --git a/ios/plugins/BeaconPlugin/Sources/SwiftUIBeaconPlugin.swift b/ios/plugins/BeaconPlugin/Sources/SwiftUIBeaconPlugin.swift index 0650342c2..9ca2e6a10 100644 --- a/ios/plugins/BeaconPlugin/Sources/SwiftUIBeaconPlugin.swift +++ b/ios/plugins/BeaconPlugin/Sources/SwiftUIBeaconPlugin.swift @@ -27,8 +27,9 @@ public class BeaconPlugin: BaseBeaconPlugin(player: P) where P: HeadlessPlayer { guard let player = player as? SwiftUIPlayer else { return } + let beacon = self.beacon(assetBeacon:) player.hooks?.view.tap(name: "BeaconPlugin") { view in - AnyView(view.environment(\.beaconContext, BeaconContext(self.beacon(assetBeacon:)))) + AnyView(view.environment(\.beaconContext, BeaconContext(beacon))) } } } diff --git a/ios/plugins/ExpressionPlugin/Sources/ExpressionPlugin.swift b/ios/plugins/ExpressionPlugin/Sources/ExpressionPlugin.swift index 78af38f85..58cc88311 100644 --- a/ios/plugins/ExpressionPlugin/Sources/ExpressionPlugin.swift +++ b/ios/plugins/ExpressionPlugin/Sources/ExpressionPlugin.swift @@ -31,12 +31,13 @@ public class ExpressionPlugin: JSBasePlugin, NativePlugin { override public func getArguments() -> [Any] { guard let map = context?.evaluateScript("Map")?.construct(withArguments: []), - let restWrapper = context?.evaluateScript("(fn) => (context, ...args) => fn(context, args)") + let restWrapper = context?.evaluateScript("(fn) => (context, ...args) => fn(context, args)"), + let context = self.context else { return [] } for (key, value) in expressions { - let callback: @convention(block) (JSValue?, JSValue?) -> JSValue? = { (context, params) in + let callback: @convention(block) (JSValue?, JSValue?) -> JSValue? = { (_, params) in let args = params?.toObject() as? [Any] ?? [] - return JSValue(object: value(args), in: self.context) + return JSValue(object: value(args), in: context) } let jsCallback = JSValue(object: callback, in: context) map.invokeMethod("set", withArguments: [key, restWrapper.call(withArguments: [jsCallback as Any]) as Any]) diff --git a/ios/plugins/ExternalActionPlugin/Sources/ExternalActionPlugin.swift b/ios/plugins/ExternalActionPlugin/Sources/ExternalActionPlugin.swift index 1cc9cb02c..5d34d6797 100644 --- a/ios/plugins/ExternalActionPlugin/Sources/ExternalActionPlugin.swift +++ b/ios/plugins/ExternalActionPlugin/Sources/ExternalActionPlugin.swift @@ -42,13 +42,13 @@ public class ExternalActionPlugin: JSBasePlugin, NativePlugin { - returns: An array of arguments to construct the plugin */ override public func getArguments() -> [Any] { - let callback: @convention(block) (JSValue, JSValue) -> JSValue? = { (state, options) in + let callback: @convention(block) (JSValue, JSValue) -> JSValue? = { [weak self] (state, options) in guard - let context = self.context, + let context = self?.context, let controllers = PlayerControllers(from: options), let promise = JSUtilities.createPromise(context: context, handler: { (resolve, reject) in do { - try self.handler?(NavigationFlowExternalState(state), controllers) { transition in + try self?.handler?(NavigationFlowExternalState(state), controllers) { transition in resolve(transition) } } catch { diff --git a/ios/plugins/ExternalActionViewModifierPlugin/Sources/ExternalActionViewModifierPlugin.swift b/ios/plugins/ExternalActionViewModifierPlugin/Sources/ExternalActionViewModifierPlugin.swift index d8fc6f1f0..6c5e2338d 100644 --- a/ios/plugins/ExternalActionViewModifierPlugin/Sources/ExternalActionViewModifierPlugin.swift +++ b/ios/plugins/ExternalActionViewModifierPlugin/Sources/ExternalActionViewModifierPlugin.swift @@ -63,22 +63,22 @@ open class ExternalActionViewModifierPlugin [Any] { - let callback: @convention(block) (JSValue, JSValue) -> JSValue? = { (state, options) in + let callback: @convention(block) (JSValue, JSValue) -> JSValue? = { [weak self] (state, options) in guard - let context = self.context, + let context = self?.context, let controllers = PlayerControllers(from: options), let promise = JSUtilities.createPromise(context: context, handler: { (resolve, reject) in - self.isExternalState = true + self?.isExternalState = true let state = NavigationFlowExternalState(state) - self.state = state + self?.state = state do { - self.content = try self.handler?(state, controllers) { transition in + self?.content = try self?.handler?(state, controllers) { transition in resolve(transition) withAnimation { - self.isExternalState = false - self.state = nil + self?.isExternalState = false + self?.state = nil } - self.content = nil + self?.content = nil } } catch { reject(JSValue(newErrorFromMessage: error.playerDescription, in: context) as Any) diff --git a/ios/plugins/MetricsPlugin/Sources/MetricsPlugin.swift b/ios/plugins/MetricsPlugin/Sources/MetricsPlugin.swift index 083707c1e..7d98647e4 100644 --- a/ios/plugins/MetricsPlugin/Sources/MetricsPlugin.swift +++ b/ios/plugins/MetricsPlugin/Sources/MetricsPlugin.swift @@ -22,8 +22,8 @@ public class RequestTimePlugin: NativePlugin { public func apply

(player: P) where P: HeadlessPlayer { requestTimeWebPlugin.context = player.jsPlayerReference?.context - player.applyTo(MetricsPlugin.self) { plugin in - self.requestTimeWebPlugin.pluginRef?.invokeMethod("apply", withArguments: [plugin]) + player.applyTo(MetricsPlugin.self) { [weak self] plugin in + self?.requestTimeWebPlugin.pluginRef?.invokeMethod("apply", withArguments: [plugin]) } } } @@ -74,9 +74,10 @@ public class MetricsPlugin: JSBasePlugin, NativePlugin, WithSymbol { public func apply

(player: P) where P: HeadlessPlayer { guard trackRenderTime, let player = player as? SwiftUIPlayer else { return } + let renderEnd = self.renderEnd player.hooks?.view.tap(name: pluginName, { (view) -> AnyView in AnyView(view.onAppear { - self.renderEnd() + renderEnd() }) }) } diff --git a/ios/plugins/SwiftUICheckPathPlugin/Sources/SwiftUICheckPathPlugin.swift b/ios/plugins/SwiftUICheckPathPlugin/Sources/SwiftUICheckPathPlugin.swift index b04025315..4d638b20c 100644 --- a/ios/plugins/SwiftUICheckPathPlugin/Sources/SwiftUICheckPathPlugin.swift +++ b/ios/plugins/SwiftUICheckPathPlugin/Sources/SwiftUICheckPathPlugin.swift @@ -12,7 +12,7 @@ public class SwiftUICheckPathPlugin: BaseCheckPathPlugin, NativePlugin { public func apply

(player: P) where P: HeadlessPlayer { guard let player = player as? SwiftUIPlayer else { return } - player.hooks?.view.tap(name: self.pluginName) { view in + player.hooks?.view.tap(name: self.pluginName) { [weak self] view in AnyView(view.environment(\.checkPath, self)) } } diff --git a/scripts/after-shipit-pod-push.js b/scripts/after-shipit-pod-push.js index fc819eb47..3126b274f 100644 --- a/scripts/after-shipit-pod-push.js +++ b/scripts/after-shipit-pod-push.js @@ -43,7 +43,7 @@ class AfterShipItPodPush { auto.logger.log.info('Pushing Pod to trunk') let process try { - process = execSync('bundle exec pod trunk push --skip-tests ./bazel-bin/PlayerUI.podspec') + process = execSync('bundle exec pod trunk push --verbose --skip-tests ./bazel-bin/PlayerUI.podspec') } catch(e) { auto.logger.log.error('Pod push failed: ', process && process.stderr.toString(), e) throw e