From 81d8889efdfb173d091cc13f01e6a046e4f55733 Mon Sep 17 00:00:00 2001 From: CI Date: Fri, 28 Nov 2025 17:17:03 +0100 Subject: [PATCH 1/3] refactor(ios): shared property listener implementation --- ios/BaseHybridViewModelProperty.swift | 78 ++++++++++++++++++++++++ ios/HybridViewModelBooleanProperty.swift | 26 +++----- ios/HybridViewModelColorProperty.swift | 26 +++----- ios/HybridViewModelEnumProperty.swift | 26 +++----- ios/HybridViewModelNumberProperty.swift | 27 +++----- ios/HybridViewModelStringProperty.swift | 25 +++----- ios/HybridViewModelTriggerProperty.swift | 23 +++---- 7 files changed, 126 insertions(+), 105 deletions(-) create mode 100644 ios/BaseHybridViewModelProperty.swift diff --git a/ios/BaseHybridViewModelProperty.swift b/ios/BaseHybridViewModelProperty.swift new file mode 100644 index 00000000..64bc2445 --- /dev/null +++ b/ios/BaseHybridViewModelProperty.swift @@ -0,0 +1,78 @@ +import Foundation +import RiveRuntime + +/// Protocol for Rive property types that support listener management +protocol RivePropertyWithListeners: AnyObject { + func removeListener(_ id: UUID) +} + +typealias BooleanPropertyType = RiveDataBindingViewModel.Instance.BooleanProperty +typealias NumberPropertyType = RiveDataBindingViewModel.Instance.NumberProperty +typealias StringPropertyType = RiveDataBindingViewModel.Instance.StringProperty +typealias EnumPropertyType = RiveDataBindingViewModel.Instance.EnumProperty +typealias ColorPropertyType = RiveDataBindingViewModel.Instance.ColorProperty +typealias TriggerPropertyType = RiveDataBindingViewModel.Instance.TriggerProperty +typealias ImagePropertyType = RiveDataBindingViewModel.Instance.ImageProperty + +// Make all Rive property types conform to the protocol +extension BooleanPropertyType: RivePropertyWithListeners {} +extension NumberPropertyType: RivePropertyWithListeners {} +extension StringPropertyType: RivePropertyWithListeners {} +extension EnumPropertyType: RivePropertyWithListeners {} +extension ColorPropertyType: RivePropertyWithListeners {} +extension TriggerPropertyType: RivePropertyWithListeners {} +extension ImagePropertyType: RivePropertyWithListeners {} + +/// Helper class for managing ViewModel property listeners +/// Similar to Android's BaseHybridViewModelPropertyImpl, provides reusable listener management +class PropertyListenerHelper { + private var listenerIds: [UUID] = [] + weak var property: PropertyType? + + init(property: PropertyType) { + self.property = property + } + + /// Adds a listener and automatically tracks its ID for later cleanup + /// - Parameter addListener: Closure that adds the listener to the property and returns the listener ID + func trackListener(_ addListener: (PropertyType) -> UUID) { + guard let property = property else { return } + let id = addListener(property) + listenerIds.append(id) + } + + func removeListeners() throws { + guard let property = property else { return } + for id in listenerIds { + property.removeListener(id) + } + listenerIds.removeAll() + } + + func dispose() throws { + try? removeListeners() + } +} + +/// Protocol that provides common functionality for all hybrid ViewModel property classes +/// Reduces boilerplate by providing default implementations for listener management +protocol ViewModelPropertyProtocol { + associatedtype PropertyType: RivePropertyWithListeners + + var helper: PropertyListenerHelper { get } + + func removeListeners() throws + func dispose() throws +} + +/// Default implementations for common listener management methods +extension ViewModelPropertyProtocol { + func removeListeners() throws { + try helper.removeListeners() + } + + func dispose() throws { + try helper.dispose() + } +} + diff --git a/ios/HybridViewModelBooleanProperty.swift b/ios/HybridViewModelBooleanProperty.swift index 2ea23d82..b7933e1e 100644 --- a/ios/HybridViewModelBooleanProperty.swift +++ b/ios/HybridViewModelBooleanProperty.swift @@ -1,11 +1,11 @@ import NitroModules import RiveRuntime -class HybridViewModelBooleanProperty: HybridViewModelBooleanPropertySpec { - private var property: RiveDataBindingViewModel.Instance.BooleanProperty! - private var listenerIds: [UUID] = [] +class HybridViewModelBooleanProperty: HybridViewModelBooleanPropertySpec, ViewModelPropertyProtocol { + private var property: BooleanPropertyType! + lazy var helper = PropertyListenerHelper(property: property!) - init(property: RiveDataBindingViewModel.Instance.BooleanProperty) { + init(property: BooleanPropertyType) { self.property = property super.init() } @@ -28,20 +28,10 @@ class HybridViewModelBooleanProperty: HybridViewModelBooleanPropertySpec { } func addListener(onChanged: @escaping (Bool) -> Void) throws { - let id = property.addListener({ value in - onChanged(value) - }) - listenerIds.append(id) - } - - func removeListeners() throws { - for id in listenerIds { - property.removeListener(id) + helper.trackListener { property in + property.addListener { value in + onChanged(value) + } } - listenerIds.removeAll() - } - - func dispose() throws { - try? removeListeners() } } diff --git a/ios/HybridViewModelColorProperty.swift b/ios/HybridViewModelColorProperty.swift index f5dccd83..f749c445 100644 --- a/ios/HybridViewModelColorProperty.swift +++ b/ios/HybridViewModelColorProperty.swift @@ -1,11 +1,11 @@ import NitroModules import RiveRuntime -class HybridViewModelColorProperty: HybridViewModelColorPropertySpec { - private var property: RiveDataBindingViewModel.Instance.ColorProperty! - private var listenerIds: [UUID] = [] +class HybridViewModelColorProperty: HybridViewModelColorPropertySpec, ViewModelPropertyProtocol { + private var property: ColorPropertyType! + lazy var helper = PropertyListenerHelper(property: property!) - init(property: RiveDataBindingViewModel.Instance.ColorProperty) { + init(property: ColorPropertyType) { self.property = property super.init() } @@ -28,21 +28,11 @@ class HybridViewModelColorProperty: HybridViewModelColorPropertySpec { } func addListener(onChanged: @escaping (Double) -> Void) throws { - let id = property.addListener({ value in - onChanged(value.toHexDouble()) - }) - listenerIds.append(id) - } - - func removeListeners() throws { - for id in listenerIds { - property.removeListener(id) + helper.trackListener { property in + property.addListener { value in + onChanged(value.toHexDouble()) + } } - listenerIds.removeAll() - } - - func dispose() throws { - try? removeListeners() } } diff --git a/ios/HybridViewModelEnumProperty.swift b/ios/HybridViewModelEnumProperty.swift index 4f7a6e34..759603d9 100644 --- a/ios/HybridViewModelEnumProperty.swift +++ b/ios/HybridViewModelEnumProperty.swift @@ -1,11 +1,11 @@ import NitroModules import RiveRuntime -class HybridViewModelEnumProperty: HybridViewModelEnumPropertySpec { - private var property: RiveDataBindingViewModel.Instance.EnumProperty! - private var listenerIds: [UUID] = [] +class HybridViewModelEnumProperty: HybridViewModelEnumPropertySpec, ViewModelPropertyProtocol { + private var property: EnumPropertyType! + lazy var helper = PropertyListenerHelper(property: property!) - init(property: RiveDataBindingViewModel.Instance.EnumProperty) { + init(property: EnumPropertyType) { self.property = property super.init() } @@ -28,20 +28,10 @@ class HybridViewModelEnumProperty: HybridViewModelEnumPropertySpec { } func addListener(onChanged: @escaping (String) -> Void) throws { - let id = property.addListener({ value in - onChanged(value) - }) - listenerIds.append(id) - } - - func removeListeners() throws { - for id in listenerIds { - property.removeListener(id) + helper.trackListener { property in + property.addListener { value in + onChanged(value) + } } - listenerIds.removeAll() - } - - func dispose() throws { - try? removeListeners() } } diff --git a/ios/HybridViewModelNumberProperty.swift b/ios/HybridViewModelNumberProperty.swift index c2edb602..baf4b228 100644 --- a/ios/HybridViewModelNumberProperty.swift +++ b/ios/HybridViewModelNumberProperty.swift @@ -1,10 +1,10 @@ import RiveRuntime -class HybridViewModelNumberProperty: HybridViewModelNumberPropertySpec { - var property: RiveDataBindingViewModel.Instance.NumberProperty! - private var listenerIds: [UUID] = [] +class HybridViewModelNumberProperty: HybridViewModelNumberPropertySpec, ViewModelPropertyProtocol { + var property: NumberPropertyType! + lazy var helper = PropertyListenerHelper(property: property!) - init(property: RiveDataBindingViewModel.Instance.NumberProperty) { + init(property: NumberPropertyType) { self.property = property super.init() } @@ -27,22 +27,11 @@ class HybridViewModelNumberProperty: HybridViewModelNumberPropertySpec { } func addListener(onChanged: @escaping (Double) -> Void) throws { - let id = property.addListener({ value in - onChanged(Double(value)) - }) - - listenerIds.append(id) - - } - - func removeListeners() throws { - for id in listenerIds { - property.removeListener(id) + helper.trackListener { property in + property.addListener { value in + onChanged(Double(value)) + } } - listenerIds.removeAll() } - func dispose() throws { - try? removeListeners() - } } diff --git a/ios/HybridViewModelStringProperty.swift b/ios/HybridViewModelStringProperty.swift index ed1ad79f..9ab95627 100644 --- a/ios/HybridViewModelStringProperty.swift +++ b/ios/HybridViewModelStringProperty.swift @@ -1,11 +1,11 @@ import NitroModules import RiveRuntime -class HybridViewModelStringProperty: HybridViewModelStringPropertySpec { - private var property: RiveDataBindingViewModel.Instance.StringProperty! - private var listenerIds: [UUID] = [] +class HybridViewModelStringProperty: HybridViewModelStringPropertySpec, ViewModelPropertyProtocol { + private var property: StringPropertyType! + lazy var helper = PropertyListenerHelper(property: property!) - init(property: RiveDataBindingViewModel.Instance.StringProperty) { + init(property: StringPropertyType) { self.property = property super.init() } @@ -28,20 +28,11 @@ class HybridViewModelStringProperty: HybridViewModelStringPropertySpec { } func addListener(onChanged: @escaping (String) -> Void) throws { - let id = property.addListener({ value in - onChanged(value) - }) - listenerIds.append(id) - } - - func removeListeners() throws { - for id in listenerIds { - property.removeListener(id) + helper.trackListener { property in + property.addListener { value in + onChanged(value) + } } - listenerIds.removeAll() } - func dispose() throws { - try? removeListeners() - } } diff --git a/ios/HybridViewModelTriggerProperty.swift b/ios/HybridViewModelTriggerProperty.swift index e652cf7a..37ed625b 100644 --- a/ios/HybridViewModelTriggerProperty.swift +++ b/ios/HybridViewModelTriggerProperty.swift @@ -1,11 +1,11 @@ import NitroModules import RiveRuntime -class HybridViewModelTriggerProperty: HybridViewModelTriggerPropertySpec { - private var property: RiveDataBindingViewModel.Instance.TriggerProperty! - private var listenerIds: [UUID] = [] +class HybridViewModelTriggerProperty: HybridViewModelTriggerPropertySpec, ViewModelPropertyProtocol { + private var property: TriggerPropertyType! + lazy var helper = PropertyListenerHelper(property: property!) - init(property: RiveDataBindingViewModel.Instance.TriggerProperty) { + init(property: TriggerPropertyType) { self.property = property super.init() } @@ -23,18 +23,11 @@ class HybridViewModelTriggerProperty: HybridViewModelTriggerPropertySpec { } func addListener(onChanged: @escaping () -> Void) throws { - let id = property.addListener({ onChanged() }) - listenerIds.append(id) - } - - func removeListeners() throws { - for id in listenerIds { - property.removeListener(id) + helper.trackListener { property in + property.addListener { + onChanged() + } } - listenerIds.removeAll() } - func dispose() throws { - try? removeListeners() - } } From 6d77a5c0cc07df517aa50fde704212132708c7ff Mon Sep 17 00:00:00 2001 From: CI Date: Mon, 1 Dec 2025 12:03:14 +0100 Subject: [PATCH 2/3] refactor: conditional addListener on type match --- ios/BaseHybridViewModelProperty.swift | 57 ++++++++++++++++-------- ios/HybridViewModelBooleanProperty.swift | 12 +---- ios/HybridViewModelColorProperty.swift | 11 +++-- ios/HybridViewModelEnumProperty.swift | 12 +---- ios/HybridViewModelNumberProperty.swift | 10 ++--- ios/HybridViewModelStringProperty.swift | 13 +----- ios/HybridViewModelTriggerProperty.swift | 21 ++++++--- 7 files changed, 69 insertions(+), 67 deletions(-) diff --git a/ios/BaseHybridViewModelProperty.swift b/ios/BaseHybridViewModelProperty.swift index 64bc2445..9bdad99e 100644 --- a/ios/BaseHybridViewModelProperty.swift +++ b/ios/BaseHybridViewModelProperty.swift @@ -3,6 +3,9 @@ import RiveRuntime /// Protocol for Rive property types that support listener management protocol RivePropertyWithListeners: AnyObject { + associatedtype ListenerValueType + + func addListener(_ callback: @escaping (ListenerValueType) -> Void) -> UUID func removeListener(_ id: UUID) } @@ -15,16 +18,24 @@ typealias TriggerPropertyType = RiveDataBindingViewModel.Instance.TriggerPropert typealias ImagePropertyType = RiveDataBindingViewModel.Instance.ImageProperty // Make all Rive property types conform to the protocol -extension BooleanPropertyType: RivePropertyWithListeners {} -extension NumberPropertyType: RivePropertyWithListeners {} -extension StringPropertyType: RivePropertyWithListeners {} -extension EnumPropertyType: RivePropertyWithListeners {} -extension ColorPropertyType: RivePropertyWithListeners {} -extension TriggerPropertyType: RivePropertyWithListeners {} -extension ImagePropertyType: RivePropertyWithListeners {} +extension BooleanPropertyType: RivePropertyWithListeners { + typealias ListenerValueType = Bool // Native: Bool → Bool (no conversion) +} +extension NumberPropertyType: RivePropertyWithListeners { + typealias ListenerValueType = Float // Native: Float → Double (needs conversion) +} +extension StringPropertyType: RivePropertyWithListeners { + typealias ListenerValueType = String // Native: String → String (no conversion) +} +extension EnumPropertyType: RivePropertyWithListeners { + typealias ListenerValueType = String // Native: String → String (no conversion) +} +extension ColorPropertyType: RivePropertyWithListeners { + typealias ListenerValueType = UIColor // Native: UIColor → Double (needs conversion) +} +// Note: TriggerProperty doesn't fit the pattern - it has () -> Void listeners, not (Void) -> Void /// Helper class for managing ViewModel property listeners -/// Similar to Android's BaseHybridViewModelPropertyImpl, provides reusable listener management class PropertyListenerHelper { private var listenerIds: [UUID] = [] weak var property: PropertyType? @@ -33,11 +44,10 @@ class PropertyListenerHelper { self.property = property } - /// Adds a listener and automatically tracks its ID for later cleanup - /// - Parameter addListener: Closure that adds the listener to the property and returns the listener ID - func trackListener(_ addListener: (PropertyType) -> UUID) { + /// Adds a listener to the property and automatically tracks its ID for cleanup + func addListener(_ callback: @escaping (PropertyType.ListenerValueType) -> Void) { guard let property = property else { return } - let id = addListener(property) + let id = property.addListener(callback) listenerIds.append(id) } @@ -54,19 +64,23 @@ class PropertyListenerHelper { } } -/// Protocol that provides common functionality for all hybrid ViewModel property classes -/// Reduces boilerplate by providing default implementations for listener management -protocol ViewModelPropertyProtocol { +/// Protocol for properties that have typed values (Bool, String, Double, etc.) +/// Provides a default addListener implementation +protocol ValuedPropertyProtocol{ associatedtype PropertyType: RivePropertyWithListeners + associatedtype ValueType + var property: PropertyType! { get } var helper: PropertyListenerHelper { get } - + + func addListener(onChanged: @escaping (ValueType) -> Void) throws func removeListeners() throws func dispose() throws } -/// Default implementations for common listener management methods -extension ViewModelPropertyProtocol { + +/// Default implementations for lifecycle methods (always available) +extension ValuedPropertyProtocol { func removeListeners() throws { try helper.removeListeners() } @@ -76,3 +90,10 @@ extension ViewModelPropertyProtocol { } } +/// Automatic addListener() ONLY when ListenerValueType == ValueType (no conversion needed) +extension ValuedPropertyProtocol where PropertyType.ListenerValueType == ValueType { + func addListener(onChanged: @escaping (ValueType) -> Void) throws { + helper.addListener(onChanged) // Types match, just forward directly! + } +} + diff --git a/ios/HybridViewModelBooleanProperty.swift b/ios/HybridViewModelBooleanProperty.swift index b7933e1e..c2b7985c 100644 --- a/ios/HybridViewModelBooleanProperty.swift +++ b/ios/HybridViewModelBooleanProperty.swift @@ -1,8 +1,8 @@ import NitroModules import RiveRuntime -class HybridViewModelBooleanProperty: HybridViewModelBooleanPropertySpec, ViewModelPropertyProtocol { - private var property: BooleanPropertyType! +class HybridViewModelBooleanProperty: HybridViewModelBooleanPropertySpec, ValuedPropertyProtocol { + var property: BooleanPropertyType! lazy var helper = PropertyListenerHelper(property: property!) init(property: BooleanPropertyType) { @@ -26,12 +26,4 @@ class HybridViewModelBooleanProperty: HybridViewModelBooleanPropertySpec, ViewMo property.value = newValue } } - - func addListener(onChanged: @escaping (Bool) -> Void) throws { - helper.trackListener { property in - property.addListener { value in - onChanged(value) - } - } - } } diff --git a/ios/HybridViewModelColorProperty.swift b/ios/HybridViewModelColorProperty.swift index f749c445..c8bfba3b 100644 --- a/ios/HybridViewModelColorProperty.swift +++ b/ios/HybridViewModelColorProperty.swift @@ -1,8 +1,8 @@ import NitroModules import RiveRuntime -class HybridViewModelColorProperty: HybridViewModelColorPropertySpec, ViewModelPropertyProtocol { - private var property: ColorPropertyType! +class HybridViewModelColorProperty: HybridViewModelColorPropertySpec, ValuedPropertyProtocol { + var property: ColorPropertyType! lazy var helper = PropertyListenerHelper(property: property!) init(property: ColorPropertyType) { @@ -27,11 +27,10 @@ class HybridViewModelColorProperty: HybridViewModelColorPropertySpec, ViewModelP } } + // Custom addListener because we need to convert UIColor → Double func addListener(onChanged: @escaping (Double) -> Void) throws { - helper.trackListener { property in - property.addListener { value in - onChanged(value.toHexDouble()) - } + helper.addListener { (color: UIColor) in + onChanged(color.toHexDouble()) } } } diff --git a/ios/HybridViewModelEnumProperty.swift b/ios/HybridViewModelEnumProperty.swift index 759603d9..c7f6a79d 100644 --- a/ios/HybridViewModelEnumProperty.swift +++ b/ios/HybridViewModelEnumProperty.swift @@ -1,8 +1,8 @@ import NitroModules import RiveRuntime -class HybridViewModelEnumProperty: HybridViewModelEnumPropertySpec, ViewModelPropertyProtocol { - private var property: EnumPropertyType! +class HybridViewModelEnumProperty: HybridViewModelEnumPropertySpec, ValuedPropertyProtocol { + var property: EnumPropertyType! lazy var helper = PropertyListenerHelper(property: property!) init(property: EnumPropertyType) { @@ -26,12 +26,4 @@ class HybridViewModelEnumProperty: HybridViewModelEnumPropertySpec, ViewModelPro property.value = newValue } } - - func addListener(onChanged: @escaping (String) -> Void) throws { - helper.trackListener { property in - property.addListener { value in - onChanged(value) - } - } - } } diff --git a/ios/HybridViewModelNumberProperty.swift b/ios/HybridViewModelNumberProperty.swift index baf4b228..9173cb21 100644 --- a/ios/HybridViewModelNumberProperty.swift +++ b/ios/HybridViewModelNumberProperty.swift @@ -1,6 +1,6 @@ import RiveRuntime -class HybridViewModelNumberProperty: HybridViewModelNumberPropertySpec, ViewModelPropertyProtocol { +class HybridViewModelNumberProperty: HybridViewModelNumberPropertySpec, ValuedPropertyProtocol { var property: NumberPropertyType! lazy var helper = PropertyListenerHelper(property: property!) @@ -26,12 +26,10 @@ class HybridViewModelNumberProperty: HybridViewModelNumberPropertySpec, ViewMode } } + // Custom addListener needed because ListenerValueType (Float) != ValueType (Double) func addListener(onChanged: @escaping (Double) -> Void) throws { - helper.trackListener { property in - property.addListener { value in - onChanged(Double(value)) - } + helper.addListener { (value: Float) in + onChanged(Double(value)) } } - } diff --git a/ios/HybridViewModelStringProperty.swift b/ios/HybridViewModelStringProperty.swift index 9ab95627..e96dfc84 100644 --- a/ios/HybridViewModelStringProperty.swift +++ b/ios/HybridViewModelStringProperty.swift @@ -1,8 +1,8 @@ import NitroModules import RiveRuntime -class HybridViewModelStringProperty: HybridViewModelStringPropertySpec, ViewModelPropertyProtocol { - private var property: StringPropertyType! +class HybridViewModelStringProperty: HybridViewModelStringPropertySpec, ValuedPropertyProtocol { + var property: StringPropertyType! lazy var helper = PropertyListenerHelper(property: property!) init(property: StringPropertyType) { @@ -26,13 +26,4 @@ class HybridViewModelStringProperty: HybridViewModelStringPropertySpec, ViewMode property.value = newValue } } - - func addListener(onChanged: @escaping (String) -> Void) throws { - helper.trackListener { property in - property.addListener { value in - onChanged(value) - } - } - } - } diff --git a/ios/HybridViewModelTriggerProperty.swift b/ios/HybridViewModelTriggerProperty.swift index 37ed625b..aa07100b 100644 --- a/ios/HybridViewModelTriggerProperty.swift +++ b/ios/HybridViewModelTriggerProperty.swift @@ -1,9 +1,9 @@ import NitroModules import RiveRuntime -class HybridViewModelTriggerProperty: HybridViewModelTriggerPropertySpec, ViewModelPropertyProtocol { +class HybridViewModelTriggerProperty: HybridViewModelTriggerPropertySpec { private var property: TriggerPropertyType! - lazy var helper = PropertyListenerHelper(property: property!) + private var listenerIds: [UUID] = [] init(property: TriggerPropertyType) { self.property = property @@ -23,11 +23,20 @@ class HybridViewModelTriggerProperty: HybridViewModelTriggerPropertySpec, ViewMo } func addListener(onChanged: @escaping () -> Void) throws { - helper.trackListener { property in - property.addListener { - onChanged() - } + let id = property.addListener { + onChanged() } + listenerIds.append(id) } + func removeListeners() throws { + for id in listenerIds { + property.removeListener(id) + } + listenerIds.removeAll() + } + + func dispose() throws { + try? removeListeners() + } } From 0c06757dd9cea522c9c63562ea8219afe69ef9bb Mon Sep 17 00:00:00 2001 From: CI Date: Mon, 1 Dec 2025 12:16:52 +0100 Subject: [PATCH 3/3] chore: linting --- ios/BaseHybridViewModelProperty.swift | 6 ++---- ios/HybridViewModel.swift | 18 +++++++++--------- ios/HybridViewModelInstance.swift | 18 +++++++++--------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/ios/BaseHybridViewModelProperty.swift b/ios/BaseHybridViewModelProperty.swift index 9bdad99e..87efb26c 100644 --- a/ios/BaseHybridViewModelProperty.swift +++ b/ios/BaseHybridViewModelProperty.swift @@ -66,19 +66,18 @@ class PropertyListenerHelper { /// Protocol for properties that have typed values (Bool, String, Double, etc.) /// Provides a default addListener implementation -protocol ValuedPropertyProtocol{ +protocol ValuedPropertyProtocol { associatedtype PropertyType: RivePropertyWithListeners associatedtype ValueType var property: PropertyType! { get } var helper: PropertyListenerHelper { get } - + func addListener(onChanged: @escaping (ValueType) -> Void) throws func removeListeners() throws func dispose() throws } - /// Default implementations for lifecycle methods (always available) extension ValuedPropertyProtocol { func removeListeners() throws { @@ -96,4 +95,3 @@ extension ValuedPropertyProtocol where PropertyType.ListenerValueType == ValueTy helper.addListener(onChanged) // Types match, just forward directly! } } - diff --git a/ios/HybridViewModel.swift b/ios/HybridViewModel.swift index eafe0ac5..0f7cc256 100644 --- a/ios/HybridViewModel.swift +++ b/ios/HybridViewModel.swift @@ -2,34 +2,34 @@ import RiveRuntime class HybridViewModel: HybridViewModelSpec { let viewModel: RiveDataBindingViewModel? - + init(viewModel: RiveDataBindingViewModel) { self.viewModel = viewModel } - + override init() { self.viewModel = nil super.init() } - + var propertyCount: Double { Double(viewModel?.propertyCount ?? 0) } - + var instanceCount: Double { Double(viewModel?.instanceCount ?? 0) } - + var modelName: String { viewModel?.name ?? "" } - + func createInstanceByIndex(index: Double) throws -> (any HybridViewModelInstanceSpec)? { guard let viewModel = viewModel, let vmi = viewModel.createInstance(fromIndex: UInt(index)) else { return nil } return HybridViewModelInstance(viewModelInstance: vmi) } - + func createInstanceByName(name: String) throws -> (any HybridViewModelInstanceSpec)? { guard let viewModel = viewModel, let vmi = viewModel.createInstance(fromName: name) else { return nil } return HybridViewModelInstance(viewModelInstance: vmi) } - + func createDefaultInstance() throws -> (any HybridViewModelInstanceSpec)? { guard let viewModel = viewModel, let vmi = viewModel.createDefaultInstance() else { @@ -37,7 +37,7 @@ class HybridViewModel: HybridViewModelSpec { } return HybridViewModelInstance(viewModelInstance: vmi) } - + func createInstance() throws -> (any HybridViewModelInstanceSpec)? { guard let viewModel = viewModel, let vmi = viewModel.createInstance() else { return nil } diff --git a/ios/HybridViewModelInstance.swift b/ios/HybridViewModelInstance.swift index 57cde0d9..abbc4932 100644 --- a/ios/HybridViewModelInstance.swift +++ b/ios/HybridViewModelInstance.swift @@ -2,43 +2,43 @@ import RiveRuntime class HybridViewModelInstance: HybridViewModelInstanceSpec { let viewModelInstance: RiveDataBindingViewModel.Instance? - + init(viewModelInstance: RiveDataBindingViewModel.Instance) { self.viewModelInstance = viewModelInstance } - + override init() { self.viewModelInstance = nil super.init() } - + var instanceName: String { viewModelInstance?.name ?? "" } - + func numberProperty(path: String) throws -> (any HybridViewModelNumberPropertySpec)? { guard let property = viewModelInstance?.numberProperty(fromPath: path) else { return nil } return HybridViewModelNumberProperty(property: property) } - + func stringProperty(path: String) throws -> (any HybridViewModelStringPropertySpec)? { guard let property = viewModelInstance?.stringProperty(fromPath: path) else { return nil } return HybridViewModelStringProperty(property: property) } - + func booleanProperty(path: String) throws -> (any HybridViewModelBooleanPropertySpec)? { guard let property = viewModelInstance?.booleanProperty(fromPath: path) else { return nil } return HybridViewModelBooleanProperty(property: property) } - + func colorProperty(path: String) throws -> (any HybridViewModelColorPropertySpec)? { guard let property = viewModelInstance?.colorProperty(fromPath: path) else { return nil } return HybridViewModelColorProperty(property: property) } - + func enumProperty(path: String) throws -> (any HybridViewModelEnumPropertySpec)? { guard let property = viewModelInstance?.enumProperty(fromPath: path) else { return nil } return HybridViewModelEnumProperty(property: property) } - + func triggerProperty(path: String) throws -> (any HybridViewModelTriggerPropertySpec)? { guard let property = viewModelInstance?.triggerProperty(fromPath: path) else { return nil } return HybridViewModelTriggerProperty(property: property)